Index: NutriMatch/Areas/Identity/Pages/Account/Login.cshtml
===================================================================
--- NutriMatch/Areas/Identity/Pages/Account/Login.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Areas/Identity/Pages/Account/Login.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,112 @@
+﻿@page
+@model LoginModel
+@{
+    ViewData["Title"] = "Log in";
+}
+<style>
+    :root {
+        --bs-primary: #22c55e;
+        --bs-primary-rgb: 34, 197, 94;
+    }
+    .btn-primary {
+        background-color: #22c55e;
+        border-color: #22c55e;
+    }
+    .btn-primary:hover {
+        background-color: #16a34a;
+        border-color: #16a34a;
+    }
+    .btn-primary:focus, .btn-primary.focus {
+        box-shadow: 0 0 0 0.2rem rgba(34, 197, 94, 0.5);
+    }
+    .btn-primary:active, .btn-primary.active {
+        background-color: #15803d !important;
+        border-color: #15803d !important;
+    }
+    .btn-outline-primary {
+        color: #22c55e;
+        border-color: #22c55e;
+    }
+    .btn-outline-primary:hover {
+        background-color: #22c55e;
+        border-color: #22c55e;
+        color: white;
+    }
+    .btn-outline-primary:focus, .btn-outline-primary.focus {
+        box-shadow: 0 0 0 0.2rem rgba(34, 197, 94, 0.5);
+    }
+    .btn-outline-primary:active, .btn-outline-primary.active {
+        background-color: #15803d !important;
+        border-color: #15803d !important;
+        color: white !important;
+    }
+    .form-control:focus {
+        border-color: #86efac;
+        box-shadow: 0 0 0 0.2rem rgba(34, 197, 94, 0.25);
+    }
+    h1 {
+        color: #22c55e;
+        font-weight: 600;
+    }
+    .register-section {
+        background-color: #f0fdf4;
+        border-radius: 8px;
+        padding: 30px;
+        text-align: center;
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+    }
+    .register-section h3 {
+        color: #16a34a;
+        margin-bottom: 20px;
+    }
+    a {
+        color: #22c55e;
+    }
+    a:hover {
+        color: #16a34a;
+    }
+    #account {
+        margin-top: 5rem;
+    }
+</style>
+<div class="row mt-5 d-flex justify-content-center">
+    <div class="col-md-4">
+        <section>
+            <form id="account" method="post">
+                <h2>Log in to your account.</h2>
+                <hr />
+                <div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div>
+                <div class="form-floating mb-3">
+                    <input asp-for="Input.Email" class="form-control" autocomplete="username" aria-required="true" placeholder="name@example.com" />
+                    <label asp-for="Input.Email" class="form-label">Email</label>
+                    <span asp-validation-for="Input.Email" class="text-danger"></span>
+                </div>
+                <div class="form-floating mb-3">
+                    <input asp-for="Input.Password" class="form-control" autocomplete="current-password" aria-required="true" placeholder="password" />
+                    <label asp-for="Input.Password" class="form-label">Password</label>
+                    <span asp-validation-for="Input.Password" class="text-danger"></span>
+                </div>
+                <div>
+                    <button id="login-submit" type="submit" class="w-100 btn btn-lg btn-primary">Log in</button>
+                </div>
+                <div>
+                    <p>
+                        <a id="forgot-password" asp-page="./ForgotPassword">Forgot your password?</a>
+                    </p>
+                </div>
+            </form>
+        </section>
+    </div>
+    <div class="d-flex align-items-center col-md-6 col-md-offset-2">
+        <section class="register-section">
+            <h3>New here?</h3>
+            <p class="mb-3">Create an account to get started with all our features.</p>
+            <a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl" class="btn btn-outline-primary btn-lg">Create Account</a>
+        </section>
+    </div>
+</div>
+@section Scripts {
+    <partial name="_ValidationScriptsPartial" />
+}
Index: NutriMatch/Areas/Identity/Pages/Account/Login.cshtml.cs
===================================================================
--- NutriMatch/Areas/Identity/Pages/Account/Login.cshtml.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Areas/Identity/Pages/Account/Login.cshtml.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,85 @@
+
+#nullable disable
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Identity.UI.Services;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+using Microsoft.Extensions.Logging;
+using NutriMatch.Models;
+namespace NutriMatch.Areas.Identity.Pages.Account
+{
+    public class LoginModel : PageModel
+    {
+        private readonly SignInManager<User> _signInManager;
+        private readonly ILogger<LoginModel> _logger;
+        public LoginModel(SignInManager<User> signInManager, ILogger<LoginModel> logger)
+        {
+            _signInManager = signInManager;
+            _logger = logger;
+        }
+        [BindProperty]
+        public InputModel Input { get; set; }
+        public IList<AuthenticationScheme> ExternalLogins { get; set; }
+        public string ReturnUrl { get; set; }
+        [TempData]
+        public string ErrorMessage { get; set; }
+        public class InputModel
+        {
+            [Required]
+            [EmailAddress]
+            public string Email { get; set; }
+            [Required]
+            [DataType(DataType.Password)]
+            public string Password { get; set; }
+            [Display(Name = "Remember me?")]
+            public bool RememberMe { get; set; }
+        }
+        public async Task OnGetAsync(string returnUrl = null)
+        {
+            if (!string.IsNullOrEmpty(ErrorMessage))
+            {
+                ModelState.AddModelError(string.Empty, ErrorMessage);
+            }
+            returnUrl ??= Url.Content("~/");
+            await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
+            ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
+            ReturnUrl = returnUrl;
+        }
+        public async Task<IActionResult> OnPostAsync(string returnUrl = null)
+        {
+            returnUrl ??= Url.Content("~/");
+            ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
+            if (ModelState.IsValid)
+            {
+                var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
+                if (result.Succeeded)
+                {
+                    _logger.LogInformation("User logged in.");
+                    return LocalRedirect(returnUrl);
+                }
+                if (result.RequiresTwoFactor)
+                {
+                    return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe });
+                }
+                if (result.IsLockedOut)
+                {
+                    _logger.LogWarning("User account locked out.");
+                    return RedirectToPage("./Lockout");
+                }
+                else
+                {
+                    ModelState.AddModelError(string.Empty, "Invalid login attempt.");
+                    return Page();
+                }
+            }
+            return Page();
+        }
+    }
+}
Index: NutriMatch/Areas/Identity/Pages/Account/Logout.cshtml
===================================================================
--- NutriMatch/Areas/Identity/Pages/Account/Logout.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Areas/Identity/Pages/Account/Logout.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,27 @@
+﻿@page
+@model LogoutModel
+@{
+    ViewData["Title"] = "Log out";
+}
+
+<style>
+    #logout-section {
+        margin-top: 10rem;
+    }
+</style>
+
+<header>
+    <h1>@ViewData["Title"]</h1>
+    @{
+        if (User.Identity?.IsAuthenticated ?? false)
+        {
+            <form id="logout-section" class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/", new { area = "" })" method="post">
+                <button type="submit" class="nav-link btn btn-link text-dark">Click here to Logout</button>
+            </form>
+        }
+        else
+        {
+            <p>You have successfully logged out of the application.</p>
+        }
+    }
+</header>
Index: NutriMatch/Areas/Identity/Pages/Account/Logout.cshtml.cs
===================================================================
--- NutriMatch/Areas/Identity/Pages/Account/Logout.cshtml.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Areas/Identity/Pages/Account/Logout.cshtml.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,36 @@
+
+#nullable disable
+using System;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+using Microsoft.Extensions.Logging;
+using NutriMatch.Models;
+namespace NutriMatch.Areas.Identity.Pages.Account
+{
+    public class LogoutModel : PageModel
+    {
+        private readonly SignInManager<User> _signInManager;
+        private readonly ILogger<LogoutModel> _logger;
+        public LogoutModel(SignInManager<User> signInManager, ILogger<LogoutModel> logger)
+        {
+            _signInManager = signInManager;
+            _logger = logger;
+        }
+        public async Task<IActionResult> OnPost(string returnUrl = null)
+        {
+            await _signInManager.SignOutAsync();
+            _logger.LogInformation("User logged out.");
+            if (returnUrl != null)
+            {
+                return LocalRedirect(returnUrl);
+            }
+            else
+            {
+                return RedirectToPage();
+            }
+        }
+    }
+}
Index: NutriMatch/Areas/Identity/Pages/Account/Manage/Index.cshtml
===================================================================
--- NutriMatch/Areas/Identity/Pages/Account/Manage/Index.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Areas/Identity/Pages/Account/Manage/Index.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,30 @@
+﻿@page
+@model IndexModel
+@{
+    ViewData["Title"] = "Profile";
+    ViewData["ActivePage"] = ManageNavPages.Index;
+}
+
+<h3>@ViewData["Title"]</h3>
+<partial name="_StatusMessage" for="StatusMessage" />
+<div class="row">
+    <div class="col-md-6">
+        <form id="profile-form" method="post">
+            <div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div>
+            <div class="form-floating mb-3">
+                <input asp-for="Username" class="form-control" placeholder="Please choose your username." disabled />
+                <label asp-for="Username" class="form-label"></label>
+            </div>
+            <div class="form-floating mb-3">
+                <input asp-for="Input.PhoneNumber" class="form-control" placeholder="Please enter your phone number."/>
+                <label asp-for="Input.PhoneNumber" class="form-label"></label>
+                <span asp-validation-for="Input.PhoneNumber" class="text-danger"></span>
+            </div>
+            <button id="update-profile-button" type="submit" class="w-100 btn btn-lg btn-primary">Save</button>
+        </form>
+    </div>
+</div>
+
+@section Scripts {
+    <partial name="_ValidationScriptsPartial" />
+}
Index: NutriMatch/Areas/Identity/Pages/Account/Manage/Index.cshtml.cs
===================================================================
--- NutriMatch/Areas/Identity/Pages/Account/Manage/Index.cshtml.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Areas/Identity/Pages/Account/Manage/Index.cshtml.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,82 @@
+
+#nullable disable
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.Text.Encodings.Web;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+using NutriMatch.Models;
+namespace NutriMatch.Areas.Identity.Pages.Account.Manage
+{
+    public class IndexModel : PageModel
+    {
+        private readonly UserManager<User> _userManager;
+        private readonly SignInManager<User> _signInManager;
+        public IndexModel(
+            UserManager<User> userManager,
+            SignInManager<User> signInManager)
+        {
+            _userManager = userManager;
+            _signInManager = signInManager;
+        }
+        public string Username { get; set; }
+        [TempData]
+        public string StatusMessage { get; set; }
+        [BindProperty]
+        public InputModel Input { get; set; }
+        public class InputModel
+        {
+            [Phone]
+            [Display(Name = "Phone number")]
+            public string PhoneNumber { get; set; }
+        }
+        private async Task LoadAsync(User user)
+        {
+            var userName = await _userManager.GetUserNameAsync(user);
+            var phoneNumber = await _userManager.GetPhoneNumberAsync(user);
+            Username = userName;
+            Input = new InputModel
+            {
+                PhoneNumber = phoneNumber
+            };
+        }
+        public async Task<IActionResult> OnGetAsync()
+        {
+            var user = await _userManager.GetUserAsync(User);
+            if (user == null)
+            {
+                return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
+            }
+            await LoadAsync(user);
+            return Page();
+        }
+        public async Task<IActionResult> OnPostAsync()
+        {
+            var user = await _userManager.GetUserAsync(User);
+            if (user == null)
+            {
+                return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
+            }
+            if (!ModelState.IsValid)
+            {
+                await LoadAsync(user);
+                return Page();
+            }
+            var phoneNumber = await _userManager.GetPhoneNumberAsync(user);
+            if (Input.PhoneNumber != phoneNumber)
+            {
+                var setPhoneResult = await _userManager.SetPhoneNumberAsync(user, Input.PhoneNumber);
+                if (!setPhoneResult.Succeeded)
+                {
+                    StatusMessage = "Unexpected error when trying to set phone number.";
+                    return RedirectToPage();
+                }
+            }
+            await _signInManager.RefreshSignInAsync(user);
+            StatusMessage = "Your profile has been updated";
+            return RedirectToPage();
+        }
+    }
+}
Index: NutriMatch/Areas/Identity/Pages/Account/Manage/ManageNavPages.cs
===================================================================
--- NutriMatch/Areas/Identity/Pages/Account/Manage/ManageNavPages.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Areas/Identity/Pages/Account/Manage/ManageNavPages.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,32 @@
+
+#nullable disable
+using System;
+using Microsoft.AspNetCore.Mvc.Rendering;
+namespace  NutriMatch.Areas.Identity.Pages.Account.Manage
+{
+    public static class ManageNavPages
+    {
+        public static string Index => "Index";
+        public static string Email => "Email";
+        public static string ChangePassword => "ChangePassword";
+        public static string DownloadPersonalData => "DownloadPersonalData";
+        public static string DeletePersonalData => "DeletePersonalData";
+        public static string ExternalLogins => "ExternalLogins";
+        public static string PersonalData => "PersonalData";
+        public static string TwoFactorAuthentication => "TwoFactorAuthentication";
+        public static string IndexNavClass(ViewContext viewContext) => PageNavClass(viewContext, Index);
+        public static string EmailNavClass(ViewContext viewContext) => PageNavClass(viewContext, Email);
+        public static string ChangePasswordNavClass(ViewContext viewContext) => PageNavClass(viewContext, ChangePassword);
+        public static string DownloadPersonalDataNavClass(ViewContext viewContext) => PageNavClass(viewContext, DownloadPersonalData);
+        public static string DeletePersonalDataNavClass(ViewContext viewContext) => PageNavClass(viewContext, DeletePersonalData);
+        public static string ExternalLoginsNavClass(ViewContext viewContext) => PageNavClass(viewContext, ExternalLogins);
+        public static string PersonalDataNavClass(ViewContext viewContext) => PageNavClass(viewContext, PersonalData);
+        public static string TwoFactorAuthenticationNavClass(ViewContext viewContext) => PageNavClass(viewContext, TwoFactorAuthentication);
+        public static string PageNavClass(ViewContext viewContext, string page)
+        {
+            var activePage = viewContext.ViewData["ActivePage"] as string
+                ?? System.IO.Path.GetFileNameWithoutExtension(viewContext.ActionDescriptor.DisplayName);
+            return string.Equals(activePage, page, StringComparison.OrdinalIgnoreCase) ? "active" : null;
+        }
+    }
+}
Index: NutriMatch/Areas/Identity/Pages/Account/Manage/_ManageNav.cshtml
===================================================================
--- NutriMatch/Areas/Identity/Pages/Account/Manage/_ManageNav.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Areas/Identity/Pages/Account/Manage/_ManageNav.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,16 @@
+@using NutriMatch.Models;
+@inject SignInManager<User> SignInManager
+@{
+    var hasExternalLogins = (await SignInManager.GetExternalAuthenticationSchemesAsync()).Any();
+}
+<ul class="nav nav-pills flex-column">
+    <li class="nav-item"><a class="nav-link @ManageNavPages.IndexNavClass(ViewContext)" id="profile" asp-page="./Index">Profile</a></li>
+    <li class="nav-item"><a class="nav-link @ManageNavPages.EmailNavClass(ViewContext)" id="email" asp-page="./Email">Email</a></li>
+    <li class="nav-item"><a class="nav-link @ManageNavPages.ChangePasswordNavClass(ViewContext)" id="change-password" asp-page="./ChangePassword">Password</a></li>
+    @if (hasExternalLogins)
+    {
+        <li id="external-logins" class="nav-item"><a id="external-login" class="nav-link @ManageNavPages.ExternalLoginsNavClass(ViewContext)" asp-page="./ExternalLogins">External logins</a></li>
+    }
+    <li class="nav-item"><a class="nav-link @ManageNavPages.TwoFactorAuthenticationNavClass(ViewContext)" id="two-factor" asp-page="./TwoFactorAuthentication">Two-factor authentication</a></li>
+    <li class="nav-item"><a class="nav-link @ManageNavPages.PersonalDataNavClass(ViewContext)" id="personal-data" asp-page="./PersonalData">Personal data</a></li>
+</ul>
Index: NutriMatch/Areas/Identity/Pages/Account/Manage/_ViewImports.cshtml
===================================================================
--- NutriMatch/Areas/Identity/Pages/Account/Manage/_ViewImports.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Areas/Identity/Pages/Account/Manage/_ViewImports.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,1 @@
+@using NutriMatch.Areas.Identity.Pages.Account.Manage
Index: NutriMatch/Areas/Identity/Pages/Account/MyAccount.cshtml
===================================================================
--- NutriMatch/Areas/Identity/Pages/Account/MyAccount.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Areas/Identity/Pages/Account/MyAccount.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,180 @@
+@page
+@model AccountModel
+@{
+    ViewData["Title"] = "Account";
+}
+<style>
+    :root {
+        --bs-primary: #22c55e;
+        --bs-primary-rgb: 34, 197, 94;
+    }
+    .btn-primary {
+        background-color: #22c55e;
+        border-color: #22c55e;
+    }
+    .btn-primary:hover {
+        background-color: #16a34a;
+        border-color: #16a34a;
+    }
+    .btn-primary:focus, .btn-primary.focus {
+        box-shadow: 0 0 0 0.2rem rgba(34, 197, 94, 0.5);
+    }
+    .btn-primary:active, .btn-primary.active {
+        background-color: #15803d !important;
+        border-color: #15803d !important;
+    }
+    .form-control:focus {
+        border-color: #86efac;
+        box-shadow: 0 0 0 0.2rem rgba(34, 197, 94, 0.25);
+    }
+    h1, h2, h3 {
+        color: #22c55e;
+        font-weight: 600;
+    }
+    .account-section {
+        background-color: #f0fdf4;
+        border-radius: 8px;
+        padding: 30px;
+        margin-bottom: 30px;
+        border: 1px solid #bbf7d0;
+    }
+    .account-section h3 {
+        color: #16a34a;
+        margin-bottom: 20px;
+        border-bottom: 2px solid #22c55e;
+        padding-bottom: 10px;
+    }
+    .alert-success {
+        background-color: #dcfce7;
+        border-color: #bbf7d0;
+        color: #166534;
+    }
+    .profile-picture-section {
+        text-align: center;
+        margin-bottom: 30px;
+    }
+    .profile-picture {
+        width: 120px;
+        height: 120px;
+        border-radius: 50%;
+        object-fit: cover;
+        border: 4px solid #22c55e;
+        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+    }
+    .profile-picture-upload {
+        margin-top: 15px;
+    }
+    .nav-pills .nav-link.text-danger:hover {
+        background-color: rgba(239, 68, 68, 0.1);
+        color: #dc2626 !important;
+    }
+    .nav-pills .nav-link {
+        color: #22c55e;
+        margin-bottom: 5px;
+    }
+    .nav-pills .nav-link:hover {
+        background-color: rgba(34, 197, 94, 0.1);
+        color: #16a34a;
+    }
+    .nav-pills .nav-link.active {
+        background-color: #22c55e;
+        color: white;
+    }
+    #whole-container {
+        margin-top: 8rem;
+    }
+</style>
+<div id="whole-container" class="container">
+    @if (!string.IsNullOrEmpty(Model.StatusMessage))
+    {
+        <div class="alert alert-success alert-dismissible fade show" role="alert">
+            @Model.StatusMessage
+            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
+        </div>
+    }
+    <div class="row">
+        <div class="col-md-3">
+            <div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist" aria-orientation="vertical">
+                <button class="nav-link @(Model.ActiveTab != "Password" ? "active" : "")" id="v-pills-profile-tab" data-bs-toggle="pill" data-bs-target="#v-pills-profile" type="button" role="tab" aria-controls="v-pills-profile" aria-selected="true">Profile</button>
+                <button class="nav-link @(Model.ActiveTab == "Password" ? "active" : "")" id="v-pills-security-tab" data-bs-toggle="pill" data-bs-target="#v-pills-security" type="button" role="tab" aria-controls="v-pills-security" aria-selected="false">Password</button>
+                <hr class="my-3">
+                <form method="post" asp-page-handler="Logout" class="d-inline">
+                    <button type="submit" class="nav-link text-danger border-0 bg-transparent w-100 text-start">
+                        <i class="fas fa-sign-out-alt me-2"></i>Log Out
+                    </button>
+                </form>
+            </div>
+        </div>
+        <div class="col-md-9">
+            <div class="tab-content" id="v-pills-tabContent">
+                <div class="tab-pane fade @(Model.ActiveTab != "Password" ? "show active" : "")" id="v-pills-profile" role="tabpanel" aria-labelledby="v-pills-profile-tab">
+                    <div class="account-section">
+                        <form method="post" asp-page-handler="UpdateProfile" enctype="multipart/form-data">
+                            <h3>Profile Information</h3>
+                            <div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div>
+                            <div class="profile-picture-section">
+                                <img src="@Model.ProfilePictureUrl" alt="Profile Picture" class="profile-picture" id="profilePreview" />
+                                <div class="profile-picture-upload">
+                                    <input asp-for="ProfileInput.ProfilePicture" type="file" class="form-control" accept="image/*" onchange="previewImage(this)" />
+                                    <small class="form-text text-muted">Upload a profile picture (JPG, PNG, or GIF, max 5MB)</small>
+                                    <span asp-validation-for="ProfileInput.ProfilePicture" class="text-danger"></span>
+                                </div>
+                            </div>
+                            <div class="form-floating mb-3">
+                                <input asp-for="ProfileInput.UserName" class="form-control" placeholder="Username" />
+                                <label asp-for="ProfileInput.UserName" class="form-label">Username</label>
+                                <span asp-validation-for="ProfileInput.UserName" class="text-danger"></span>
+                            </div>
+                            <div class="form-floating mb-3">
+                                <input asp-for="ProfileInput.Email" class="form-control" placeholder="Email" />
+                                <label asp-for="ProfileInput.Email" class="form-label">Email Address</label>
+                                <span asp-validation-for="ProfileInput.Email" class="text-danger"></span>
+                            </div>
+                            <button type="submit" class="btn btn-primary">Update Profile</button>
+                            @Html.AntiForgeryToken()
+                        </form>
+                    </div>
+                </div>
+                <div class="tab-pane fade @(Model.ActiveTab == "Password" ? "show active" : "")" id="v-pills-security" role="tabpanel" aria-labelledby="v-pills-security-tab">
+                    <div class="account-section">
+                        <form method="post" asp-page-handler="ChangePassword">
+                            <h3>Change Password</h3>
+                            <div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div>
+                            <div class="form-floating mb-3">
+                                <input asp-for="PasswordInput.CurrentPassword" type="password" class="form-control" placeholder="Current Password" />
+                                <label asp-for="PasswordInput.CurrentPassword" class="form-label">Current Password</label>
+                                <span asp-validation-for="PasswordInput.CurrentPassword" class="text-danger"></span>
+                            </div>
+                            <div class="form-floating mb-3">
+                                <input asp-for="PasswordInput.NewPassword" type="password" class="form-control" placeholder="New Password" />
+                                <label asp-for="PasswordInput.NewPassword" class="form-label">New Password</label>
+                                <span asp-validation-for="PasswordInput.NewPassword" class="text-danger"></span>
+                            </div>
+                            <div class="form-floating mb-3">
+                                <input asp-for="PasswordInput.ConfirmPassword" type="password" class="form-control" placeholder="Confirm New Password" />
+                                <label asp-for="PasswordInput.ConfirmPassword" class="form-label">Confirm New Password</label>
+                                <span asp-validation-for="PasswordInput.ConfirmPassword" class="text-danger"></span>
+                            </div>
+                            <button type="submit" class="btn btn-primary">Change Password</button>
+                            <input name="__RequestVerificationToken" type="hidden" value="@Html.AntiForgeryToken().ToString()" />
+                        </form>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<script>
+    function previewImage(input) {
+        if (input.files && input.files[0]) {
+            var reader = new FileReader();
+            reader.onload = function(e) {
+                document.getElementById('profilePreview').src = e.target.result;
+            }
+            reader.readAsDataURL(input.files[0]);
+        }
+    }
+</script>
+@section Scripts {
+    <partial name="_ValidationScriptsPartial" />
+}
Index: NutriMatch/Areas/Identity/Pages/Account/MyAccount.cshtml.cs
===================================================================
--- NutriMatch/Areas/Identity/Pages/Account/MyAccount.cshtml.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Areas/Identity/Pages/Account/MyAccount.cshtml.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,280 @@
+
+#nullable disable
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+using Microsoft.Extensions.Logging;
+using NutriMatch.Models;
+namespace NutriMatch.Areas.Identity.Pages.Account
+{
+    [Authorize]
+    public class AccountModel : PageModel
+    {
+        private readonly UserManager<User> _userManager;
+        private readonly SignInManager<User> _signInManager;
+        private readonly ILogger<AccountModel> _logger;
+        private readonly IWebHostEnvironment _webHostEnvironment;
+        public AccountModel(
+            UserManager<User> userManager,
+            SignInManager<User> signInManager,
+            ILogger<AccountModel> logger,
+            IWebHostEnvironment webHostEnvironment)
+        {
+            _userManager = userManager;
+            _signInManager = signInManager;
+            _logger = logger;
+            _webHostEnvironment = webHostEnvironment;
+        }
+        [BindProperty]
+        public ProfileInputModel ProfileInput { get; set; }
+        [BindProperty]
+        public PasswordInputModel PasswordInput { get; set; }
+        [BindProperty]
+        public string ActiveTab { get; set; }
+        [TempData]
+        public string StatusMessage { get; set; }
+        public string ProfilePictureUrl { get; set; }
+        public class ProfileInputModel
+        {
+            [Required]
+            [EmailAddress]
+            [Display(Name = "Email")]
+            public string Email { get; set; }
+            [Required]
+            [Display(Name = "Username")]
+            public string UserName { get; set; }
+            [Display(Name = "Profile Picture")]
+            public IFormFile ProfilePicture { get; set; }
+        }
+        public class PasswordInputModel
+        {
+            [Required]
+            [DataType(DataType.Password)]
+            [Display(Name = "Current Password")]
+            public string CurrentPassword { get; set; }
+            [Required]
+            [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at most {1} characters long.", MinimumLength = 6)]
+            [DataType(DataType.Password)]
+            [Display(Name = "New Password")]
+            public string NewPassword { get; set; }
+            [DataType(DataType.Password)]
+            [Display(Name = "Confirm New Password")]
+            [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
+            public string ConfirmPassword { get; set; }
+        }
+        public async Task<IActionResult> OnGetAsync()
+        {
+            var user = await _userManager.GetUserAsync(User);
+            if (user == null)
+            {
+                return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
+            }
+            await LoadUserData(user);
+            return Page();
+        }
+        public async Task<IActionResult> OnPostUpdateProfileAsync()
+        {
+            var user = await _userManager.GetUserAsync(User);
+            if (user == null)
+            {
+                return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
+            }
+            var userT = await _userManager.GetUserAsync(User);
+            bool hasChanges = false;
+            if (ProfileInput.Email != user.Email)
+            {
+                var existingUser = await _userManager.FindByEmailAsync(ProfileInput.Email);
+                if (existingUser != null && existingUser.Id != user.Id)
+                {
+                    ModelState.AddModelError($"{nameof(ProfileInput)}.{nameof(ProfileInput.Email)}", "Email is already taken.");
+                    await LoadUserData(user);
+                    return Page();
+                }
+                user.Email = ProfileInput.Email;
+                user.NormalizedEmail = _userManager.NormalizeEmail(ProfileInput.Email);
+                user.EmailConfirmed = false;
+                hasChanges = true;
+            }
+            if (ProfileInput.UserName != user.UserName)
+            {
+                var existingUser = await _userManager.FindByNameAsync(ProfileInput.UserName);
+                if (existingUser != null && existingUser.Id != user.Id)
+                {
+                    ModelState.AddModelError($"{nameof(ProfileInput)}.{nameof(ProfileInput.UserName)}", "Username is already taken.");
+                    await LoadUserData(user);
+                    return Page();
+                }
+                user.UserName = ProfileInput.UserName;
+                user.NormalizedUserName = _userManager.NormalizeName(ProfileInput.UserName);
+                hasChanges = true;
+            }
+            if (ProfileInput.ProfilePicture != null)
+            {
+                var result = await SaveProfilePictureAsync(ProfileInput.ProfilePicture, user.Id);
+                if (!result.Success)
+                {
+                    StatusMessage = result.ErrorMessage;
+                    await LoadUserData(user);
+                    return Page();
+                }
+                hasChanges = true;
+            }
+            if (hasChanges)
+            {
+                var updateResult = await _userManager.UpdateAsync(user);
+                if (!updateResult.Succeeded)
+                {
+                    foreach (var error in updateResult.Errors)
+                    {
+                        ModelState.AddModelError(string.Empty, error.Description);
+                    }
+                    await LoadUserData(user);
+                    return Page();
+                }
+                await _signInManager.RefreshSignInAsync(user);
+                StatusMessage = "Your profile has been updated successfully.";
+                _logger.LogInformation("User {UserId} updated profile. New Email: {Email}, New UserName: {UserName}", 
+                    user.Id, user.Email, user.UserName);
+                    if (!updateResult.Succeeded)
+                    {
+                        foreach (var error in updateResult.Errors)
+                        {
+                            _logger.LogError("Update failed: {Error}", error.Description);
+                            ModelState.AddModelError(string.Empty, error.Description);
+                        }
+                    }
+            }
+            else
+            {
+                _logger.LogInformation("Change failed");
+                StatusMessage = "No changes were made to your profile.";
+            }
+            return RedirectToPage();
+        }
+        public async Task<IActionResult> OnPostChangePasswordAsync()
+        {
+            var user = await _userManager.GetUserAsync(User);
+            if (user == null)
+            {
+                return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
+            }
+            var changePasswordResult = await _userManager.ChangePasswordAsync(user, PasswordInput.CurrentPassword, PasswordInput.NewPassword);
+            if (!changePasswordResult.Succeeded)
+            {
+                foreach (var error in changePasswordResult.Errors)
+                {
+                    ModelState.AddModelError($"{nameof(PasswordInput)}.{nameof(PasswordInput.CurrentPassword)}", error.Description);
+                }
+                ActiveTab = "Password";
+                await LoadUserData(user);
+                return Page();
+            }
+            await _signInManager.RefreshSignInAsync(user);
+            _logger.LogInformation("User changed their password successfully.");
+            StatusMessage = "Your password has been changed successfully.";
+            PasswordInput = new PasswordInputModel();
+            return RedirectToPage();
+        }
+        public async Task<IActionResult> OnPostLogoutAsync()
+        {
+            await _signInManager.SignOutAsync();
+            _logger.LogInformation("User logged out.");
+            return RedirectToPage("/Index");
+        }
+        private async Task LoadUserData(User user)
+        {
+            ProfileInput = new ProfileInputModel
+            {
+                Email = user.Email,
+                UserName = user.UserName
+            };
+            ProfilePictureUrl = !string.IsNullOrEmpty(user.ProfilePictureUrl) 
+                ? user.ProfilePictureUrl 
+                : GetProfilePictureUrl(user.Id);
+        }
+        private async Task<(bool Success, string ErrorMessage)> SaveProfilePictureAsync(IFormFile file, string userId)
+        {
+            try
+            {
+                if (file.Length > 5 * 1024 * 1024)
+                {
+                    return (false, "Profile picture must be smaller than 5MB.");
+                }
+                var allowedExtensions = new[] { ".jpg", ".jpeg", ".png", ".gif" };
+                var fileExtension = Path.GetExtension(file.FileName).ToLowerInvariant();
+                if (!allowedExtensions.Contains(fileExtension))
+                {
+                    return (false, "Please upload a valid image file (JPG, PNG, or GIF).");
+                }
+                var uploadsDir = Path.Combine(_webHostEnvironment.WebRootPath, "images");
+                Directory.CreateDirectory(uploadsDir);
+                await DeleteProfilePictureAsync(userId);
+                var fileName = $"{userId}_{Guid.NewGuid()}{fileExtension}";
+                var filePath = Path.Combine(uploadsDir, fileName);
+                using (var stream = new FileStream(filePath, FileMode.Create))
+                {
+                    await file.CopyToAsync(stream);
+                }
+                var user = await _userManager.FindByIdAsync(userId);
+                if (user != null)
+                {
+                    user.ProfilePictureUrl = $"/images/{fileName}";
+                    await _userManager.UpdateAsync(user);
+                }
+                return (true, null);
+            }
+            catch (Exception ex)
+            {
+                _logger.LogError(ex, "Error saving profile picture for user {UserId}", userId);
+                return (false, "An error occurred while saving the profile picture.");
+            }
+        }
+        private async Task DeleteProfilePictureAsync(string userId)
+        {
+            try
+            {
+                var uploadsDir = Path.Combine(_webHostEnvironment.WebRootPath, "images");
+                if (Directory.Exists(uploadsDir))
+                {
+                    var existingFiles = Directory.GetFiles(uploadsDir, $"{userId}_*");
+                    foreach (var file in existingFiles)
+                    {
+                        System.IO.File.Delete(file);
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                _logger.LogError(ex, "Error deleting profile picture for user {UserId}", userId);
+            }
+        }
+        private string GetProfilePictureUrl(string userId)
+        {
+            try
+            {
+                var uploadsDir = Path.Combine(_webHostEnvironment.WebRootPath, "uploads", "profile-pictures");
+                if (Directory.Exists(uploadsDir))
+                {
+                    var existingFile = Directory.GetFiles(uploadsDir, $"{userId}_*").FirstOrDefault();
+                    if (existingFile != null)
+                    {
+                        var fileName = Path.GetFileName(existingFile);
+                        return $"/uploads/profile-pictures/{fileName}";
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                _logger.LogError(ex, "Error getting profile picture URL for user {UserId}", userId);
+            }
+            return "https://via.placeholder.com/120x120/22c55e/ffffff?text=User";
+        }
+    }
+}
Index: NutriMatch/Areas/Identity/Pages/Account/Register.cshtml
===================================================================
--- NutriMatch/Areas/Identity/Pages/Account/Register.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Areas/Identity/Pages/Account/Register.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,123 @@
+﻿@page
+@model RegisterModel
+@{
+    ViewData["Title"] = "Register";
+}
+
+<style>
+    :root {
+        --bs-primary: #22c55e;
+        --bs-primary-rgb: 34, 197, 94;
+    }
+    
+    .btn-primary {
+        background-color: #22c55e;
+        border-color: #22c55e;
+    }
+    
+    .btn-primary:hover {
+        background-color: #16a34a;
+        border-color: #16a34a;
+    }
+    
+    .btn-primary:focus, .btn-primary.focus {
+        box-shadow: 0 0 0 0.2rem rgba(34, 197, 94, 0.5);
+    }
+    
+    .btn-primary:active, .btn-primary.active {
+        background-color: #15803d !important;
+        border-color: #15803d !important;
+    }
+    
+    .btn-outline-primary {
+        color: #22c55e;
+        border-color: #22c55e;
+    }
+    
+    .btn-outline-primary:hover {
+        background-color: #22c55e;
+        border-color: #22c55e;
+        color: white;
+    }
+    
+    .btn-outline-primary:focus, .btn-outline-primary.focus {
+        box-shadow: 0 0 0 0.2rem rgba(34, 197, 94, 0.5);
+    }
+    
+    .btn-outline-primary:active, .btn-outline-primary.active {
+        background-color: #15803d !important;
+        border-color: #15803d !important;
+        color: white !important;
+    }
+    
+    .form-control:focus {
+        border-color: #86efac;
+        box-shadow: 0 0 0 0.2rem rgba(34, 197, 94, 0.25);
+    }
+    
+    h1 {
+        color: #22c55e;
+        font-weight: 600;
+    }
+    
+    .login-section {
+        background-color: #f0fdf4;
+        border-radius: 8px;
+        padding: 30px;
+        text-align: center;
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+    }
+    
+    .login-section h3 {
+        color: #16a34a;
+        margin-bottom: 20px;
+    }
+
+    #registerForm {
+        margin-top: 5rem;
+    }
+</style>
+
+<div class="row mt-5 mb-5 flex justify-content-center al">
+    <div class="col-md-4">
+        <form id="registerForm" asp-route-returnUrl="@Model.ReturnUrl" method="post">
+            <h2>Create a new account.</h2>
+            <hr />
+            <div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div>
+            <div class="form-floating mb-3">
+                <input asp-for="Input.Email" class="form-control" autocomplete="username" aria-required="true" placeholder="name@example.com" />
+                <label asp-for="Input.Email">Email</label>
+                <span asp-validation-for="Input.Email" class="text-danger"></span>
+            </div>
+            <div class="form-floating mb-3">
+                <input asp-for="Input.Username" class="form-control" autocomplete="username" aria-required="true" placeholder="username" />
+                <label asp-for="Input.Username">Username</label>
+                <span asp-validation-for="Input.Username" class="text-danger"></span>
+            </div>
+            <div class="form-floating mb-3">
+                <input asp-for="Input.Password" class="form-control" autocomplete="new-password" aria-required="true" placeholder="password" />
+                <label asp-for="Input.Password">Password</label>
+                <span asp-validation-for="Input.Password" class="text-danger"></span>
+            </div>
+            <div class="form-floating mb-3">
+                <input asp-for="Input.ConfirmPassword" class="form-control" autocomplete="new-password" aria-required="true" placeholder="password" />
+                <label asp-for="Input.ConfirmPassword">Confirm Password</label>
+                <span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
+            </div>
+            <button id="registerSubmit" type="submit" class="w-100 btn btn-lg btn-primary">Register</button>
+        </form>
+    </div>
+    <div class="d-flex align-items-center col-md-6 col-md-offset-2">
+        <section class="login-section">
+            <h3>Already have an account?</h3>
+            <p class="mb-3">Sign in to access your existing account.</p>
+            <a asp-page="./Login" asp-route-returnUrl="@Model.ReturnUrl" class="btn btn-outline-primary btn-lg">Sign In</a>
+        </section>
+    </div>
+</div>
+
+@section Scripts {
+    <partial name="_ValidationScriptsPartial" />
+}
Index: NutriMatch/Areas/Identity/Pages/Account/Register.cshtml.cs
===================================================================
--- NutriMatch/Areas/Identity/Pages/Account/Register.cshtml.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Areas/Identity/Pages/Account/Register.cshtml.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,156 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Text.Encodings.Web;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Identity.UI.Services;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+using Microsoft.AspNetCore.WebUtilities;
+using Microsoft.Extensions.Logging;
+using NutriMatch.Models;
+
+namespace NutriMatch.Areas.Identity.Pages.Account
+{
+    public class RegisterModel : PageModel
+    {
+        private readonly SignInManager<User> _signInManager;
+        private readonly UserManager<User> _userManager;
+        private readonly IUserStore<User> _userStore;
+        private readonly IUserEmailStore<User> _emailStore;
+        private readonly ILogger<RegisterModel> _logger;
+        private readonly IEmailSender _emailSender;
+
+        public RegisterModel(
+            UserManager<User> userManager,
+            IUserStore<User> userStore,
+            SignInManager<User> signInManager,
+            ILogger<RegisterModel> logger,
+            IEmailSender emailSender)
+        {
+            _userManager = userManager;
+            _userStore = userStore;
+            _emailStore = GetEmailStore();
+            _signInManager = signInManager;
+            _logger = logger;
+            _emailSender = emailSender;
+        }
+
+        [BindProperty]
+        public InputModel Input { get; set; }
+
+        public string ReturnUrl { get; set; }
+
+        public IList<AuthenticationScheme> ExternalLogins { get; set; }
+
+        public class InputModel
+        {
+            [Required]
+            [EmailAddress]
+            [Display(Name = "Email")]
+            public string Email { get; set; }
+
+            [Required]
+            [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
+            [DataType(DataType.Password)]
+            [Display(Name = "Password")]
+            public string Password { get; set; }
+
+            [DataType(DataType.Password)]
+            [Display(Name = "Confirm password")]
+            [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
+            public string ConfirmPassword { get; set; }
+
+            [Required]
+            [StringLength(50, ErrorMessage = "The {0} must be at most {1} characters long.")]
+            [Display(Name = "Username")]
+            public string Username { get; set; }
+
+        }
+
+        public async Task OnGetAsync(string returnUrl = null)
+        {
+            ReturnUrl = returnUrl;
+            ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
+        }
+
+        public async Task<IActionResult> OnPostAsync(string returnUrl = null)
+        {
+            returnUrl ??= Url.Content("~/");
+            ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
+            
+            if (ModelState.IsValid)
+            {
+                var user = CreateUser();
+                user.ProfilePictureUrl = "/images/DefaultProfile.png";
+
+
+                await _userStore.SetUserNameAsync(user, Input.Username, CancellationToken.None);
+                await _emailStore.SetEmailAsync(user, Input.Email, CancellationToken.None);
+                var result = await _userManager.CreateAsync(user, Input.Password);
+
+                if (result.Succeeded)
+                {
+                    _logger.LogInformation("User created a new account with password.");
+
+                    var userId = await _userManager.GetUserIdAsync(user);
+                    var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
+                    code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
+                    var callbackUrl = Url.Page(
+                        "/Account/ConfirmEmail",
+                        pageHandler: null,
+                        values: new { area = "Identity", userId = userId, code = code, returnUrl = returnUrl },
+                        protocol: Request.Scheme);
+
+                    await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
+                        $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
+
+                    if (_userManager.Options.SignIn.RequireConfirmedAccount)
+                    {
+                        return RedirectToPage("RegisterConfirmation", new { email = Input.Email, returnUrl = returnUrl });
+                    }
+                    else
+                    {
+                        await _signInManager.SignInAsync(user, isPersistent: false);
+                        return LocalRedirect(returnUrl);
+                    }
+                }
+                foreach (var error in result.Errors)
+                {
+                    ModelState.AddModelError(string.Empty, error.Description);
+                }
+            }
+
+            return Page();
+        }
+
+        private User CreateUser()
+        {
+            try
+            {
+                return Activator.CreateInstance<User>();
+            }
+            catch
+            {
+                throw new InvalidOperationException($"Can't create an instance of '{nameof(User)}'. " +
+                    $"Make sure that '{nameof(User)}' is not an abstract class and has a parameterless constructor, or alternatively " +
+                    $"override the register page in /Areas/Identity/Pages/Account/Register.cshtml");
+            }
+        }
+
+        private IUserEmailStore<User> GetEmailStore()
+        {
+            if (!_userManager.SupportsUserEmail)
+            {
+                throw new NotSupportedException("The default UI requires a user store with email support.");
+            }
+            return (IUserEmailStore<User>)_userStore;
+        }
+    }
+}
Index: NutriMatch/Areas/Identity/Pages/Account/_ViewImports.cshtml
===================================================================
--- NutriMatch/Areas/Identity/Pages/Account/_ViewImports.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Areas/Identity/Pages/Account/_ViewImports.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,1 @@
+@using NutriMatch.Areas.Identity.Pages.Account
Index: NutriMatch/Areas/Identity/Pages/_ValidationScriptsPartial.cshtml
===================================================================
--- NutriMatch/Areas/Identity/Pages/_ValidationScriptsPartial.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Areas/Identity/Pages/_ValidationScriptsPartial.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,2 @@
+﻿<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
+<script src="~/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js"></script>
Index: NutriMatch/Areas/Identity/Pages/_ViewImports.cshtml
===================================================================
--- NutriMatch/Areas/Identity/Pages/_ViewImports.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Areas/Identity/Pages/_ViewImports.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,4 @@
+@using Microsoft.AspNetCore.Identity
+@using NutriMatch.Areas.Identity
+@using NutriMatch.Areas.Identity.Pages
+@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Index: NutriMatch/Areas/Identity/Pages/_ViewStart.cshtml
===================================================================
--- NutriMatch/Areas/Identity/Pages/_ViewStart.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Areas/Identity/Pages/_ViewStart.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,4 @@
+
+@{
+    Layout = "/Views/Shared/_Layout.cshtml";
+}
Index: NutriMatch/Controllers/AdminController.cs
===================================================================
--- NutriMatch/Controllers/AdminController.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Controllers/AdminController.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,76 @@
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using NutriMatch.Models;
+using NutriMatch.Data;
+using Microsoft.EntityFrameworkCore;
+using System.Text.Json;
+[Authorize(Roles = "Admin")]
+public class AdminController : Controller
+{
+    private readonly AppDbContext _context;
+    public AdminController(AppDbContext context)
+    {
+        _context = context;
+    }
+    public async Task<IActionResult> Index()
+    {
+        var pendingRecipes = await _context.Recipes
+            .Where(r => r.IsApproved == false)
+            .Include(r => r.User)
+            .ToListAsync();
+        return View(pendingRecipes);
+    }
+    [HttpPost]
+    [ValidateAntiForgeryToken]
+    public async Task<IActionResult> ApproveRecipe([FromBody] int recipeId)
+    {
+        var recipe = await _context.Recipes.FindAsync(recipeId);
+        if (recipe == null)
+            return NotFound("Recipe not found.");
+        recipe.IsApproved = true;
+        await _context.SaveChangesAsync();
+        return Ok("Recipe approved successfully.");
+    }
+    [HttpPost]
+    [ValidateAntiForgeryToken]
+    public async Task<IActionResult> DeclineRecipe([FromBody] int recipeId)
+    {
+        var recipe = await _context.Recipes.FindAsync(recipeId);
+        if (recipe == null)
+            return NotFound("Recipe not found.");
+        _context.Recipes.Remove(recipe);
+        await _context.SaveChangesAsync();
+        return Ok("Recipe declined successfully.");
+    }
+    [HttpPost]
+    public async Task<IActionResult> BulkApproveRecipes([FromBody] JsonElement request)
+    {
+        List<int> recipeIds = request.GetProperty("recipeIds").EnumerateArray()
+            .Select(x => x.GetInt32())
+            .ToList();
+        var recipes = await _context.Recipes
+            .Where(r => recipeIds.Contains(r.Id))
+            .ToListAsync();
+        foreach (var recipe in recipes)
+        {
+            recipe.IsApproved = true;
+            Console.WriteLine(recipe.Title + " approved");
+        }
+        await _context.SaveChangesAsync();
+        return Json(new { message = "Selected recipes approved.", success = true }); ;
+    }
+    [HttpPost]
+    [ValidateAntiForgeryToken]
+    public async Task<IActionResult> BulkDeclineRecipes([FromBody] List<int> recipeIds)
+    {
+        var recipes = await _context.Recipes
+            .Where(r => recipeIds.Contains(r.Id))
+            .ToListAsync();
+        foreach (var recipe in recipes)
+        {
+            _context.Recipes.Remove(recipe);
+        }
+        await _context.SaveChangesAsync();
+        return Ok("Selected recipes declined.");
+    }
+}
Index: NutriMatch/Controllers/HomeController.cs
===================================================================
--- NutriMatch/Controllers/HomeController.cs	(revision a8860663d8380fb13055bfa6006477787df4824f)
+++ NutriMatch/Controllers/HomeController.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -17,7 +17,15 @@
         public async Task<IActionResult> Index()
         {   
+            var recipes = await _context.Recipes.Include(r => r.User).Include(r => r.Ratings).Take(6).ToListAsync();
+            foreach (var recipe in recipes)
+            {
+                recipe.Rating = recipe.Ratings.Any() ? recipe.Ratings.Average(r => r.Rating) : 0;
+            }
             var model = new HomeViewModel
             {
-                Recipes = await _context.Recipes.Take(6).ToListAsync(),
+
+               
+
+                Recipes = recipes,
                 Restaurants = await _context.Restaurants.ToListAsync()                
             };
Index: NutriMatch/Controllers/RecipesController.cs
===================================================================
--- NutriMatch/Controllers/RecipesController.cs	(revision a8860663d8380fb13055bfa6006477787df4824f)
+++ NutriMatch/Controllers/RecipesController.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -12,56 +12,69 @@
 using Microsoft.CodeAnalysis.CSharp.Syntax;
 using System.Runtime.Intrinsics.X86;
-
-
-
+using Microsoft.AspNetCore.Authorization;
+using System.Security.Claims;
+using Microsoft.AspNet.Identity;
 namespace NutriMatch.Controllers
 {
-
-
     public class RecipesController : Controller
     {
-
-            float ConvertType(float number, string unit){
-                float result;
-                switch (unit.ToLower())
-                {
-                    case "g":
-                    case "ml":
-                        result = number / 100;
-                        break;
-                    case "oz":
-                        result = (float)(number * 28.3495 / 100);
-                        break;
-                    case "tbsp":
-                        result = (float)(number * 15 / 100); 
-                        break;
-                    case "tsp":
-                        result = (float)(number * 5 / 100); 
-                        break;
-                    case "cup":
-                        result = (float)(number * 240 / 100); 
-                        break;
-                    default:
-                        return 0;
-                }
-
+        float ConvertType(float number, string unit)
+        {
+            float result;
+            switch (unit.ToLower())
+            {
+                case "g":
+                case "ml":
+                    result = number / 100;
+                    break;
+                case "oz":
+                    result = (float)(number * 28.3495 / 100);
+                    break;
+                case "tbsp":
+                    result = (float)(number * 15 / 100);
+                    break;
+                case "tsp":
+                    result = (float)(number * 5 / 100);
+                    break;
+                case "cup":
+                    result = (float)(number * 240 / 100);
+                    break;
+                default:
+                    return 0;
+            }
             return result;
-}
-
+        }
         private readonly AppDbContext _context;
-
-        public RecipesController(AppDbContext context)
+        private readonly ILogger<RecipesController> _logger;
+        public RecipesController(AppDbContext context, ILogger<RecipesController> logger)
         {
             _context = context;
-        }
-
-        
+            _logger = logger;
+        }
         public async Task<IActionResult> Index()
         {
-            return View(await _context.Recipes.ToListAsync());
-        }
-
-        
-        public async Task<IActionResult> Details(int? id)
+            var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
+            var recipes = await _context.Recipes
+                .Include(r => r.User)
+                .Include(r => r.Ratings)
+                .ToListAsync();
+            foreach (var recipe in recipes)
+            {
+                recipe.Rating = recipe.Ratings.Any() ? recipe.Ratings.Average(r => r.Rating) : 0;
+            }
+            List<int> favoriteRecipeIds = new List<int>();
+            if (!string.IsNullOrEmpty(userId))
+            {
+                favoriteRecipeIds = await _context.FavoriteRecipes
+                    .Where(fr => fr.UserId == userId)
+                    .Select(fr => fr.RecipeId)
+                    .ToListAsync();
+            }
+            ViewBag.FavoriteRecipeIds = favoriteRecipeIds;
+            ViewBag.userId = userId;
+            return View(recipes);
+        }
+        [Route("Recipes/Details/{id}/{isOwner?}")]
+        public async Task<IActionResult> Details(int? id, bool isOwner = false)
         {
             if (id == null)
@@ -69,32 +82,41 @@
                 return NotFound();
             }
-
-            var recipe = await _context.Recipes.Include(r => r.RecipeIngredients).ThenInclude(ri => ri.Ingredient)
-                .FirstOrDefaultAsync(m => m.Id == id);
+            var recipe = await _context.Recipes.Include(r => r.User)
+            .Include(r => r.RecipeIngredients)
+            .ThenInclude(ri => ri.Ingredient)
+            .FirstOrDefaultAsync(m => m.Id == id);      
             if (recipe == null)
             {
                 return NotFound();
             }
-
+            var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
+            bool actualIsOwner = !string.IsNullOrEmpty(userId) && recipe.UserId == userId;
+            var (averageRating, totalRatings, userRating, hasUserRated) = 
+                await GetRatingDataAsync(id.Value, userId);
+            bool isFavorited = false;
+            if (!string.IsNullOrEmpty(userId))
+            {
+                isFavorited = await _context.FavoriteRecipes
+                    .AnyAsync(fr => fr.UserId == userId && fr.RecipeId == id.Value);
+            }
+            ViewBag.IsOwner = actualIsOwner;
+            ViewBag.AverageRating = averageRating;
+            ViewBag.TotalRatings = totalRatings;
+            ViewBag.UserRating = userRating;
+            ViewBag.HasUserRated = hasUserRated;
+            ViewBag.IsFavorited = isFavorited;
             return PartialView("_RecipeDetailsPartial", recipe);
         }
-
-        
+        [Authorize]
         public IActionResult Create()
         {
             return View();
         }
-
-       
         [HttpPost]
         [ValidateAntiForgeryToken]
         public async Task<IActionResult> Create([Bind("Title,Instructions")] Recipe recipe)
         {
-            
-
-
             if (ModelState.IsValid)
             {
-
                 var file = Request.Form.Files.GetFile("RecipeImage");
                 if (file != null && file.Length > 0)
@@ -103,10 +125,8 @@
                     var uniqueFileName = Guid.NewGuid().ToString() + Path.GetExtension(file.FileName);
                     var filePath = Path.Combine(uploadsFolder, uniqueFileName);
-
                     using (var stream = new FileStream(filePath, FileMode.Create))
                     {
                         await file.CopyToAsync(stream);
                     }
-
                     recipe.ImageUrl = "/images/" + uniqueFileName;
                 }
@@ -115,5 +135,5 @@
                     Console.WriteLine("No file uploaded or file is empty.");
                 }
-
+                recipe.UserId = User.FindFirstValue(ClaimTypes.NameIdentifier);
                 _context.Add(recipe);
                 await _context.SaveChangesAsync();
@@ -124,7 +144,4 @@
                 float totalCarbs = 0;
                 float totalFat = 0;
-
-
-
                 foreach (var i in ingredients)
                 {
@@ -136,9 +153,5 @@
                         Quantity = i.Quantity
                     });
-
                     Ingredient tempIngredient = _context.Ingredients.Find(i.Id);
-
-
-
                     totalCalories += ConvertType(tempIngredient.Calories, i.Unit) * i.Quantity;
                     totalProtein += ConvertType(tempIngredient.Protein, i.Unit) * i.Quantity;
@@ -146,19 +159,11 @@
                     totalFat += ConvertType(tempIngredient.Fat, i.Unit) * i.Quantity;
                 }
-
                 recipe.Calories = MathF.Round(totalCalories, MidpointRounding.AwayFromZero);
                 recipe.Protein = MathF.Round(totalProtein, MidpointRounding.AwayFromZero);
                 recipe.Carbs = MathF.Round(totalCarbs, MidpointRounding.AwayFromZero);
                 recipe.Fat = MathF.Round(totalFat, MidpointRounding.AwayFromZero);
-
-
-
                 _context.Update(recipe);
-
-
                 await _context.SaveChangesAsync();
                 return RedirectToAction(nameof(Index));
-
-
             }
             else
@@ -172,12 +177,8 @@
                     }
                 }
-
-
                 Console.WriteLine("Model state is invalid. Please check the input data.");
             }
             return View(recipe);
         }
-
-        
         public async Task<IActionResult> Edit(int? id)
         {
@@ -186,5 +187,4 @@
                 return NotFound();
             }
-
             var recipe = await _context.Recipes
         .Include(r => r.RecipeIngredients)
@@ -195,96 +195,81 @@
                 return NotFound();
             }
+            if (recipe.UserId != User.FindFirstValue(System.Security.Claims.ClaimTypes.NameIdentifier))
+            {
+                return Forbid();
+            }
             return View(recipe);
         }
-
-        
-[HttpPost]
-[ValidateAntiForgeryToken]
-public async Task<IActionResult> Edit([Bind("Id,Title,Instructions")] Recipe recipe)
-{
-
-
-    if (ModelState.IsValid)
-    {
-        var file = Request.Form.Files.GetFile("RecipeImage");
-        if (file != null && file.Length > 0)
-        {
-            var uploadsFolder = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images");
-            var uniqueFileName = Guid.NewGuid().ToString() + Path.GetExtension(file.FileName);
-            var filePath = Path.Combine(uploadsFolder, uniqueFileName);
-
-            using (var stream = new FileStream(filePath, FileMode.Create))
-            {
-                await file.CopyToAsync(stream);
-            }
-
-            recipe.ImageUrl = "/images/" + uniqueFileName;
-        }
-        else
-        {
-            
-            var existing = Request.Form["ExistingImageUrl"].ToString();
-            if (existing != null)
-            {
-                recipe.ImageUrl = existing;
-            }
-        }
-
-        await _context.RecipeIngredients.Where(ri => ri.RecipeId == recipe.Id).ExecuteDeleteAsync();
-
-        string selectedIngredients = Request.Form["Ingredients"];
-        List<SelectedIngredient> ingredients = JsonSerializer.Deserialize<List<SelectedIngredient>>(selectedIngredients);
-        float totalCalories = 0;
-        float totalProtein = 0;
-        float totalCarbs = 0;
-        float totalFat = 0;
-
-        foreach (var i in ingredients)
-        {
-            _context.RecipeIngredients.Add(new RecipeIngredient
-            {
-                RecipeId = recipe.Id,
-                IngredientId = i.Id,
-                Unit = i.Unit,
-                Quantity = i.Quantity
-            });
-
-            Ingredient tempIngredient = _context.Ingredients.Find(i.Id);
-
-            totalCalories += ConvertType(tempIngredient.Calories, i.Unit) * i.Quantity;
-            totalProtein += ConvertType(tempIngredient.Protein, i.Unit) * i.Quantity;
-            totalCarbs += ConvertType(tempIngredient.Carbs, i.Unit) * i.Quantity;
-            totalFat += ConvertType(tempIngredient.Fat, i.Unit) * i.Quantity;
-        }
-
-        recipe.Calories = MathF.Round(totalCalories, MidpointRounding.AwayFromZero);
-        recipe.Protein = MathF.Round(totalProtein, MidpointRounding.AwayFromZero);
-        recipe.Carbs = MathF.Round(totalCarbs, MidpointRounding.AwayFromZero);
-        recipe.Fat = MathF.Round(totalFat, MidpointRounding.AwayFromZero);
-
-        _context.Update(recipe);
-
-        await _context.SaveChangesAsync();
-        return RedirectToAction(nameof(Index));
-    }
-    else
-    {
-        foreach (var key in ModelState.Keys)
-        {
-            var errors = ModelState[key].Errors;
-            foreach (var error in errors)
-            {
-                Console.WriteLine($"Key: {key} - Error: {error.ErrorMessage}");
-            }
-        }
-
-        Console.WriteLine("Model state is invalid. Please check the input data.");
-    }
-
-    return View(recipe);
-}
-
-
-        
+        [HttpPost]
+        [ValidateAntiForgeryToken]
+        public async Task<IActionResult> Edit([Bind("Id,Title,Instructions")] Recipe recipe)
+        {
+            if (ModelState.IsValid)
+            {
+                var file = Request.Form.Files.GetFile("RecipeImage");
+                if (file != null && file.Length > 0)
+                {
+                    var uploadsFolder = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images");
+                    var uniqueFileName = Guid.NewGuid().ToString() + Path.GetExtension(file.FileName);
+                    var filePath = Path.Combine(uploadsFolder, uniqueFileName);
+                    using (var stream = new FileStream(filePath, FileMode.Create))
+                    {
+                        await file.CopyToAsync(stream);
+                    }
+                    recipe.ImageUrl = "/images/" + uniqueFileName;
+                }
+                else
+                {
+                    var existing = Request.Form["ExistingImageUrl"].ToString();
+                    if (existing != null)
+                    {
+                        recipe.ImageUrl = existing;
+                    }
+                }
+                await _context.RecipeIngredients.Where(ri => ri.RecipeId == recipe.Id).ExecuteDeleteAsync();
+                string selectedIngredients = Request.Form["Ingredients"];
+                List<SelectedIngredient> ingredients = JsonSerializer.Deserialize<List<SelectedIngredient>>(selectedIngredients);
+                float totalCalories = 0;
+                float totalProtein = 0;
+                float totalCarbs = 0;
+                float totalFat = 0;
+                foreach (var i in ingredients)
+                {
+                    _context.RecipeIngredients.Add(new RecipeIngredient
+                    {
+                        RecipeId = recipe.Id,
+                        IngredientId = i.Id,
+                        Unit = i.Unit,
+                        Quantity = i.Quantity
+                    });
+                    Ingredient tempIngredient = _context.Ingredients.Find(i.Id);
+                    totalCalories += ConvertType(tempIngredient.Calories, i.Unit) * i.Quantity;
+                    totalProtein += ConvertType(tempIngredient.Protein, i.Unit) * i.Quantity;
+                    totalCarbs += ConvertType(tempIngredient.Carbs, i.Unit) * i.Quantity;
+                    totalFat += ConvertType(tempIngredient.Fat, i.Unit) * i.Quantity;
+                }
+                recipe.Calories = MathF.Round(totalCalories, MidpointRounding.AwayFromZero);
+                recipe.Protein = MathF.Round(totalProtein, MidpointRounding.AwayFromZero);
+                recipe.Carbs = MathF.Round(totalCarbs, MidpointRounding.AwayFromZero);
+                recipe.Fat = MathF.Round(totalFat, MidpointRounding.AwayFromZero);
+                recipe.UserId = User.FindFirstValue(ClaimTypes.NameIdentifier);
+                _context.Update(recipe);
+                await _context.SaveChangesAsync();
+                return RedirectToAction(nameof(MyRecipes));
+            }
+            else
+            {
+                foreach (var key in ModelState.Keys)
+                {
+                    var errors = ModelState[key].Errors;
+                    foreach (var error in errors)
+                    {
+                        Console.WriteLine($"Key: {key} - Error: {error.ErrorMessage}");
+                    }
+                }
+                Console.WriteLine("Model state is invalid. Please check the input data.");
+            }
+            return View(recipe);
+        }
         public async Task<IActionResult> Delete(int? id)
         {
@@ -293,5 +278,4 @@
                 return NotFound();
             }
-
             var recipe = await _context.Recipes.Include(r => r.RecipeIngredients)
                 .FirstOrDefaultAsync(m => m.Id == id);
@@ -300,9 +284,6 @@
                 return NotFound();
             }
-
-            return PartialView("_RecipeDeletePartial",recipe);
-        }
-
-        
+            return PartialView("_RecipeDeletePartial", recipe);
+        }
         [HttpPost, ActionName("Delete")]
         [ValidateAntiForgeryToken]
@@ -314,15 +295,11 @@
                 _context.Recipes.Remove(recipe);
             }
-
             await _context.SaveChangesAsync();
             return RedirectToAction(nameof(Index));
         }
-
         private bool RecipeExists(int id)
         {
             return _context.Recipes.Any(e => e.Id == id);
         }
-
-        
         public async Task<ActionResult<List<Ingredient>>> getSuggestions([FromQuery] String query)
         {
@@ -332,14 +309,198 @@
             .Take(5)
             .ToListAsync();
-
             return suggestions;
         }
-
-        
-        
-
-      
-       
-
-    } 
-}
+        public ActionResult MyRecipes()
+        {
+            var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); 
+            var userRecipes = _context.Recipes.Where(r => r.UserId == userId).Include(r => r.User).Include(r => r.Ratings).ToList();
+            var recipeIds = userRecipes.Select(r => r.Id).ToList();
+            var ratings = _context.RecipeRatings.Where(r => recipeIds.Contains(r.RecipeId)).GroupBy(r => r.RecipeId);
+             foreach (var recipe in userRecipes)
+            {
+                recipe.Rating = recipe.Ratings.Any() ? recipe.Ratings.Average(r => r.Rating) : 0;
+            }
+            double averageRating = 0;
+            foreach (var groop in ratings)
+            {
+                averageRating += groop.Average(r => r.Rating);
+            }    
+            ViewBag.AverageRating = Math.Round(averageRating / ratings.Count(), 1);
+            return View(userRecipes);
+        }
+        [HttpPost]
+        [Authorize]
+        public async Task<IActionResult> Rate([FromBody] JsonElement body)
+        {
+            int recipeId = body.GetProperty("recipeId").GetInt32();
+            double rating = body.GetProperty("rating").GetDouble();
+            try
+            {
+                var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
+                if (string.IsNullOrEmpty(userId))
+                {
+                    return Json(new { success = false, message = "User not authenticated" });
+                }
+                if (rating < 1 || rating > 5)
+                {
+                    Console.WriteLine(rating);
+                    Console.WriteLine(recipeId);
+                    return Json(new { success = false, message = "Rating must be between 1 and 5" });
+                }
+                var recipe = await _context.Recipes.FindAsync(recipeId);
+                if (recipe == null)
+                {
+                    return Json(new { success = false, message = "Recipe not found" });
+                }
+                var existingRating = await _context.RecipeRatings
+                    .FirstOrDefaultAsync(r => r.UserId == userId && r.RecipeId == recipeId);
+                if (existingRating != null)
+                {
+                    existingRating.Rating = rating;
+                    _context.RecipeRatings.Update(existingRating);
+                }
+                else
+                {
+                    var newRating = new RecipeRating
+                    {
+                        UserId = userId,
+                        RecipeId = recipeId,
+                        Rating = rating
+                    };
+                    _context.RecipeRatings.Add(newRating);
+                }
+                await _context.SaveChangesAsync();
+                var ratings = await _context.RecipeRatings
+                    .Where(r => r.RecipeId == recipeId)
+                    .Select(r => r.Rating)
+                    .ToListAsync();
+                var averageRating = ratings.Any() ? Math.Round(ratings.Average(), 1) : 0;
+                var totalRatings = ratings.Count;
+                return Json(new 
+                { 
+                    success = true, 
+                    averageRating = averageRating,
+                    totalRatings = totalRatings,
+                    message = "Rating submitted successfully"
+                });
+            }
+            catch (Exception ex)
+            {
+                return Json(new { success = false, message = "An error occurred while submitting your rating" });
+            }
+        }
+        [HttpPost]
+        [Authorize]
+        [ValidateAntiForgeryToken]
+        public async Task<IActionResult> RemoveRating([FromBody] JsonElement body)
+        {
+            int recipeId = body.GetProperty("recipeId").GetInt32();
+            try
+            {
+                var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
+                if (string.IsNullOrEmpty(userId))
+                {
+                    return Json(new { success = false, message = "User not authenticated" });
+                }
+                var existingRating = await _context.RecipeRatings
+                    .FirstOrDefaultAsync(r => r.UserId == userId && r.RecipeId == recipeId);
+                if (existingRating == null)
+                {
+                    return Json(new { success = false, message = "No rating found to remove" });
+                }
+                _context.RecipeRatings.Remove(existingRating);
+                await _context.SaveChangesAsync();
+                var ratings = await _context.RecipeRatings
+                    .Where(r => r.RecipeId == recipeId)
+                    .Select(r => r.Rating)
+                    .ToListAsync();
+                var averageRating = ratings.Any() ? Math.Round(ratings.Average(), 1) : 0;
+                var totalRatings = ratings.Count;
+                return Json(new
+                {
+                    success = true,
+                    averageRating = averageRating,
+                    totalRatings = totalRatings,
+                    message = "Rating removed successfully"
+                });
+            }
+            catch (Exception ex)
+            {
+                return Json(new { success = false, message = "An error occurred while removing your rating" });
+            }
+        }
+        private async Task<(double averageRating, int totalRatings, double userRating, bool hasUserRated)> 
+            GetRatingDataAsync(int recipeId, string userId = null)
+        {
+            var ratings = await _context.RecipeRatings
+                .Where(r => r.RecipeId == recipeId)
+                .Select(r => new { r.Rating, r.UserId })
+                .ToListAsync();
+            var averageRating = ratings.Any() ? Math.Round(ratings.Average(r => r.Rating), 1) : 0;
+            var totalRatings = ratings.Count;
+            double userRating = 0;
+            bool hasUserRated = false;
+            if (!string.IsNullOrEmpty(userId))
+            {
+                var userRatingData = ratings.FirstOrDefault(r => r.UserId == userId);
+                if (userRatingData != null)
+                {
+                    userRating = userRatingData.Rating;
+                    hasUserRated = true;
+                }
+            }
+            return (averageRating, totalRatings, userRating, hasUserRated);
+        }
+        [HttpPost]
+        [ValidateAntiForgeryToken]
+        public async Task<IActionResult> ToggleFavorite([FromBody] JsonElement request)
+        {
+            try
+            {
+                var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
+                if (string.IsNullOrEmpty(userId))
+                {
+                    return Json(new { success = false, message = "User not authenticated" });
+                }
+                int recipeId = request.GetProperty("recipeId").GetInt32();
+                var recipe = await _context.Recipes.FindAsync(recipeId);
+                if (recipe == null)
+                {
+                    return Json(new { success = false, message = "Recipe not found" });
+                }
+                var existingFavorite = await _context.FavoriteRecipes
+                    .FirstOrDefaultAsync(fr => fr.UserId == userId && fr.RecipeId == recipeId);
+                bool isFavorited;
+                if (existingFavorite != null)
+                {
+                    _context.FavoriteRecipes.Remove(existingFavorite);
+                    isFavorited = false;
+                }
+                else
+                {
+                    var favoriteRecipe = new FavoriteRecipe
+                    {
+                        UserId = userId,
+                        RecipeId = recipeId
+                    };
+                    _context.FavoriteRecipes.Add(favoriteRecipe);
+                    isFavorited = true;
+                }
+                await _context.SaveChangesAsync();
+                return Json(new { 
+                    success = true, 
+                    isFavorited = isFavorited,
+                    message = isFavorited ? "Added to favorites" : "Removed from favorites"
+                });
+            }
+            catch (Exception ex)
+            {
+                _logger?.LogError(ex, "Error toggling favorite for recipe", ex);
+                return Json(new { 
+                    success = false, 
+                    message = "An error occurred while updating favorites" 
+                });
+            }
+        }
+    }
+} 
Index: NutriMatch/Data/AppDbContext.cs
===================================================================
--- NutriMatch/Data/AppDbContext.cs	(revision a8860663d8380fb13055bfa6006477787df4824f)
+++ NutriMatch/Data/AppDbContext.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -2,7 +2,10 @@
 using NutriMatch.Models;
 
+using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
+
+
 namespace NutriMatch.Data
 {
-    public class AppDbContext : DbContext
+    public class AppDbContext : IdentityDbContext<User>
     {
         public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
@@ -12,10 +15,54 @@
 
         public DbSet<Ingredient> Ingredients { get; set; }
-        
+
         public DbSet<RestaurantMeal> RestaurantMeals { get; set; }
-        
+
         public DbSet<Restaurant> Restaurants { get; set; }
 
-       
+        public DbSet<FavoriteRecipe> FavoriteRecipes { get; set; }
+
+        public DbSet<RecipeRating> RecipeRatings { get; set; }
+
+        protected override void OnModelCreating(ModelBuilder modelBuilder)
+        {
+            base.OnModelCreating(modelBuilder); 
+
+            modelBuilder.Entity<Recipe>()
+                .HasOne(r => r.User)
+                .WithMany(u => u.Recipes)
+                .HasForeignKey(r => r.UserId)
+                .OnDelete(DeleteBehavior.Cascade);
+
+            modelBuilder.Entity<FavoriteRecipe>()
+            .HasKey(fr => new { fr.UserId, fr.RecipeId });
+
+            modelBuilder.Entity<FavoriteRecipe>()
+                .HasOne(fr => fr.User)
+                .WithMany(u => u.FavoriteRecipes)
+                .HasForeignKey(fr => fr.UserId);
+
+            modelBuilder.Entity<FavoriteRecipe>()
+                .HasOne(fr => fr.Recipe)
+                .WithMany(r => r.FavoritedBy)
+                .HasForeignKey(fr => fr.RecipeId);
+
+            modelBuilder.Entity<RecipeRating>()
+            .HasIndex(rr => new { rr.UserId, rr.RecipeId })
+            .IsUnique();
+
+            modelBuilder.Entity<RecipeRating>()
+                .HasOne(rr => rr.User)
+                .WithMany(u => u.Ratings)
+                .HasForeignKey(rr => rr.UserId);
+
+            modelBuilder.Entity<RecipeRating>()
+                .HasOne(rr => rr.Recipe)
+                .WithMany(r => r.Ratings)
+                .HasForeignKey(rr => rr.RecipeId);
+
+        }
     }
+
+   
+
 }
Index: NutriMatch/Data/DbInitializer.cs
===================================================================
--- NutriMatch/Data/DbInitializer.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Data/DbInitializer.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,28 @@
+using Microsoft.AspNetCore.Identity;
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Threading.Tasks;
+using NutriMatch.Models;
+public class DbInitializer
+{
+    public static async Task SeedRolesAsync(IServiceProvider serviceProvider)
+    {
+        var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
+        var userManager = serviceProvider.GetRequiredService<UserManager<User>>();
+        string[] roles = { "Admin", "User" };
+        foreach (var role in roles)
+        {
+            if (!await roleManager.RoleExistsAsync(role))
+                await roleManager.CreateAsync(new IdentityRole(role));
+        }
+        string adminEmail = "admin@nutrimatch.com";
+        string adminPassword = "Admin123!";
+        var adminUser = await userManager.FindByEmailAsync(adminEmail);
+        if (adminUser == null)
+        {
+            adminUser = new User { UserName = adminEmail, Email = adminEmail, EmailConfirmed = true };
+            await userManager.CreateAsync(adminUser, adminPassword);
+            await userManager.AddToRoleAsync(adminUser, "Admin");
+        }
+    }
+}
Index: NutriMatch/Migrations/20250721154024_Identity.Designer.cs
===================================================================
--- NutriMatch/Migrations/20250721154024_Identity.Designer.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Migrations/20250721154024_Identity.Designer.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,354 @@
+﻿// <auto-generated />
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using NutriMatch.Data;
+#nullable disable
+namespace NutriMatch.Migrations
+{
+    [DbContext(typeof(AppDbContext))]
+    [Migration("20250721154024_Identity")]
+    partial class Identity
+    {
+        protected override void BuildTargetModel(ModelBuilder modelBuilder)
+        {
+#pragma warning disable 612, 618
+            modelBuilder
+                .HasAnnotation("ProductVersion", "9.0.7")
+                .HasAnnotation("Relational:MaxIdentifierLength", 63);
+            NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
+                {
+                    b.Property<string>("Id")
+                        .HasColumnType("text");
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken()
+                        .HasColumnType("text");
+                    b.Property<string>("Name")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<string>("NormalizedName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.HasKey("Id");
+                    b.HasIndex("NormalizedName")
+                        .IsUnique()
+                        .HasDatabaseName("RoleNameIndex");
+                    b.ToTable("AspNetRoles", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<string>("ClaimType")
+                        .HasColumnType("text");
+                    b.Property<string>("ClaimValue")
+                        .HasColumnType("text");
+                    b.Property<string>("RoleId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("RoleId");
+                    b.ToTable("AspNetRoleClaims", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<string>("ClaimType")
+                        .HasColumnType("text");
+                    b.Property<string>("ClaimValue")
+                        .HasColumnType("text");
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("UserId");
+                    b.ToTable("AspNetUserClaims", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
+                {
+                    b.Property<string>("LoginProvider")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("ProviderKey")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("ProviderDisplayName")
+                        .HasColumnType("text");
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("LoginProvider", "ProviderKey");
+                    b.HasIndex("UserId");
+                    b.ToTable("AspNetUserLogins", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
+                {
+                    b.Property<string>("UserId")
+                        .HasColumnType("text");
+                    b.Property<string>("RoleId")
+                        .HasColumnType("text");
+                    b.HasKey("UserId", "RoleId");
+                    b.HasIndex("RoleId");
+                    b.ToTable("AspNetUserRoles", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
+                {
+                    b.Property<string>("UserId")
+                        .HasColumnType("text");
+                    b.Property<string>("LoginProvider")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("Name")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("Value")
+                        .HasColumnType("text");
+                    b.HasKey("UserId", "LoginProvider", "Name");
+                    b.ToTable("AspNetUserTokens", (string)null);
+                });
+            modelBuilder.Entity("NutriMatch.Models.Ingredient", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<float>("Calories")
+                        .HasColumnType("real");
+                    b.Property<float>("Carbs")
+                        .HasColumnType("real");
+                    b.Property<float>("Fat")
+                        .HasColumnType("real");
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<float>("Protein")
+                        .HasColumnType("real");
+                    b.HasKey("Id");
+                    b.ToTable("Ingredients");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Recipe", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<float>("Calories")
+                        .HasColumnType("real");
+                    b.Property<float>("Carbs")
+                        .HasColumnType("real");
+                    b.Property<float>("Fat")
+                        .HasColumnType("real");
+                    b.Property<string>("ImageUrl")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.PrimitiveCollection<string[]>("Instructions")
+                        .HasColumnType("text[]");
+                    b.Property<float>("Protein")
+                        .HasColumnType("real");
+                    b.Property<float>("Rating")
+                        .HasColumnType("real");
+                    b.Property<string>("Title")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.ToTable("Recipes");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RecipeIngredient", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<int>("IngredientId")
+                        .HasColumnType("integer");
+                    b.Property<float>("Quantity")
+                        .HasColumnType("real");
+                    b.Property<int>("RecipeId")
+                        .HasColumnType("integer");
+                    b.Property<string>("Unit")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("IngredientId");
+                    b.HasIndex("RecipeId");
+                    b.ToTable("RecipeIngredients");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Restaurant", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<string>("Description")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("ImageUrl")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.ToTable("Restaurants");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RestaurantMeal", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<float>("Calories")
+                        .HasColumnType("real");
+                    b.Property<float>("Carbs")
+                        .HasColumnType("real");
+                    b.Property<float>("Fat")
+                        .HasColumnType("real");
+                    b.Property<string>("ItemDescription")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("ItemName")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<float>("Protein")
+                        .HasColumnType("real");
+                    b.Property<int?>("RestaurantId")
+                        .HasColumnType("integer");
+                    b.Property<string>("RestaurantName")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("RestaurantId");
+                    b.ToTable("RestaurantMeals");
+                });
+            modelBuilder.Entity("NutriMatch.Models.User", b =>
+                {
+                    b.Property<string>("Id")
+                        .HasColumnType("text");
+                    b.Property<int>("AccessFailedCount")
+                        .HasColumnType("integer");
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken()
+                        .HasColumnType("text");
+                    b.Property<string>("Email")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<bool>("EmailConfirmed")
+                        .HasColumnType("boolean");
+                    b.Property<bool>("LockoutEnabled")
+                        .HasColumnType("boolean");
+                    b.Property<DateTimeOffset?>("LockoutEnd")
+                        .HasColumnType("timestamp with time zone");
+                    b.Property<string>("NormalizedEmail")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<string>("NormalizedUserName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<string>("PasswordHash")
+                        .HasColumnType("text");
+                    b.Property<string>("PhoneNumber")
+                        .HasColumnType("text");
+                    b.Property<bool>("PhoneNumberConfirmed")
+                        .HasColumnType("boolean");
+                    b.Property<string>("SecurityStamp")
+                        .HasColumnType("text");
+                    b.Property<bool>("TwoFactorEnabled")
+                        .HasColumnType("boolean");
+                    b.Property<string>("UserName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.HasKey("Id");
+                    b.HasIndex("NormalizedEmail")
+                        .HasDatabaseName("EmailIndex");
+                    b.HasIndex("NormalizedUserName")
+                        .IsUnique()
+                        .HasDatabaseName("UserNameIndex");
+                    b.ToTable("AspNetUsers", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
+                {
+                    b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+                        .WithMany()
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
+                {
+                    b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+                        .WithMany()
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("NutriMatch.Models.RecipeIngredient", b =>
+                {
+                    b.HasOne("NutriMatch.Models.Ingredient", "Ingredient")
+                        .WithMany()
+                        .HasForeignKey("IngredientId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.HasOne("NutriMatch.Models.Recipe", null)
+                        .WithMany("RecipeIngredients")
+                        .HasForeignKey("RecipeId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.Navigation("Ingredient");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RestaurantMeal", b =>
+                {
+                    b.HasOne("NutriMatch.Models.Restaurant", "Restaurant")
+                        .WithMany("RestaurantMeals")
+                        .HasForeignKey("RestaurantId");
+                    b.Navigation("Restaurant");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Recipe", b =>
+                {
+                    b.Navigation("RecipeIngredients");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Restaurant", b =>
+                {
+                    b.Navigation("RestaurantMeals");
+                });
+#pragma warning restore 612, 618
+        }
+    }
+}
Index: NutriMatch/Migrations/20250721154024_Identity.cs
===================================================================
--- NutriMatch/Migrations/20250721154024_Identity.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Migrations/20250721154024_Identity.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,198 @@
+﻿using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+#nullable disable
+namespace NutriMatch.Migrations
+{
+    public partial class Identity : Migration
+    {
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.CreateTable(
+                name: "AspNetRoles",
+                columns: table => new
+                {
+                    Id = table.Column<string>(type: "text", nullable: false),
+                    Name = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
+                    NormalizedName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
+                    ConcurrencyStamp = table.Column<string>(type: "text", nullable: true)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_AspNetRoles", x => x.Id);
+                });
+            migrationBuilder.CreateTable(
+                name: "AspNetUsers",
+                columns: table => new
+                {
+                    Id = table.Column<string>(type: "text", nullable: false),
+                    UserName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
+                    NormalizedUserName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
+                    Email = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
+                    NormalizedEmail = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
+                    EmailConfirmed = table.Column<bool>(type: "boolean", nullable: false),
+                    PasswordHash = table.Column<string>(type: "text", nullable: true),
+                    SecurityStamp = table.Column<string>(type: "text", nullable: true),
+                    ConcurrencyStamp = table.Column<string>(type: "text", nullable: true),
+                    PhoneNumber = table.Column<string>(type: "text", nullable: true),
+                    PhoneNumberConfirmed = table.Column<bool>(type: "boolean", nullable: false),
+                    TwoFactorEnabled = table.Column<bool>(type: "boolean", nullable: false),
+                    LockoutEnd = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
+                    LockoutEnabled = table.Column<bool>(type: "boolean", nullable: false),
+                    AccessFailedCount = table.Column<int>(type: "integer", nullable: false)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_AspNetUsers", x => x.Id);
+                });
+            migrationBuilder.CreateTable(
+                name: "AspNetRoleClaims",
+                columns: table => new
+                {
+                    Id = table.Column<int>(type: "integer", nullable: false)
+                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+                    RoleId = table.Column<string>(type: "text", nullable: false),
+                    ClaimType = table.Column<string>(type: "text", nullable: true),
+                    ClaimValue = table.Column<string>(type: "text", nullable: true)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
+                    table.ForeignKey(
+                        name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
+                        column: x => x.RoleId,
+                        principalTable: "AspNetRoles",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                });
+            migrationBuilder.CreateTable(
+                name: "AspNetUserClaims",
+                columns: table => new
+                {
+                    Id = table.Column<int>(type: "integer", nullable: false)
+                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+                    UserId = table.Column<string>(type: "text", nullable: false),
+                    ClaimType = table.Column<string>(type: "text", nullable: true),
+                    ClaimValue = table.Column<string>(type: "text", nullable: true)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
+                    table.ForeignKey(
+                        name: "FK_AspNetUserClaims_AspNetUsers_UserId",
+                        column: x => x.UserId,
+                        principalTable: "AspNetUsers",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                });
+            migrationBuilder.CreateTable(
+                name: "AspNetUserLogins",
+                columns: table => new
+                {
+                    LoginProvider = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: false),
+                    ProviderKey = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: false),
+                    ProviderDisplayName = table.Column<string>(type: "text", nullable: true),
+                    UserId = table.Column<string>(type: "text", nullable: false)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
+                    table.ForeignKey(
+                        name: "FK_AspNetUserLogins_AspNetUsers_UserId",
+                        column: x => x.UserId,
+                        principalTable: "AspNetUsers",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                });
+            migrationBuilder.CreateTable(
+                name: "AspNetUserRoles",
+                columns: table => new
+                {
+                    UserId = table.Column<string>(type: "text", nullable: false),
+                    RoleId = table.Column<string>(type: "text", nullable: false)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
+                    table.ForeignKey(
+                        name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
+                        column: x => x.RoleId,
+                        principalTable: "AspNetRoles",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                    table.ForeignKey(
+                        name: "FK_AspNetUserRoles_AspNetUsers_UserId",
+                        column: x => x.UserId,
+                        principalTable: "AspNetUsers",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                });
+            migrationBuilder.CreateTable(
+                name: "AspNetUserTokens",
+                columns: table => new
+                {
+                    UserId = table.Column<string>(type: "text", nullable: false),
+                    LoginProvider = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: false),
+                    Name = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: false),
+                    Value = table.Column<string>(type: "text", nullable: true)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
+                    table.ForeignKey(
+                        name: "FK_AspNetUserTokens_AspNetUsers_UserId",
+                        column: x => x.UserId,
+                        principalTable: "AspNetUsers",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                });
+            migrationBuilder.CreateIndex(
+                name: "IX_AspNetRoleClaims_RoleId",
+                table: "AspNetRoleClaims",
+                column: "RoleId");
+            migrationBuilder.CreateIndex(
+                name: "RoleNameIndex",
+                table: "AspNetRoles",
+                column: "NormalizedName",
+                unique: true);
+            migrationBuilder.CreateIndex(
+                name: "IX_AspNetUserClaims_UserId",
+                table: "AspNetUserClaims",
+                column: "UserId");
+            migrationBuilder.CreateIndex(
+                name: "IX_AspNetUserLogins_UserId",
+                table: "AspNetUserLogins",
+                column: "UserId");
+            migrationBuilder.CreateIndex(
+                name: "IX_AspNetUserRoles_RoleId",
+                table: "AspNetUserRoles",
+                column: "RoleId");
+            migrationBuilder.CreateIndex(
+                name: "EmailIndex",
+                table: "AspNetUsers",
+                column: "NormalizedEmail");
+            migrationBuilder.CreateIndex(
+                name: "UserNameIndex",
+                table: "AspNetUsers",
+                column: "NormalizedUserName",
+                unique: true);
+        }
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropTable(
+                name: "AspNetRoleClaims");
+            migrationBuilder.DropTable(
+                name: "AspNetUserClaims");
+            migrationBuilder.DropTable(
+                name: "AspNetUserLogins");
+            migrationBuilder.DropTable(
+                name: "AspNetUserRoles");
+            migrationBuilder.DropTable(
+                name: "AspNetUserTokens");
+            migrationBuilder.DropTable(
+                name: "AspNetRoles");
+            migrationBuilder.DropTable(
+                name: "AspNetUsers");
+        }
+    }
+}
Index: NutriMatch/Migrations/20250802174947_AddUserRecipeRelation.Designer.cs
===================================================================
--- NutriMatch/Migrations/20250802174947_AddUserRecipeRelation.Designer.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Migrations/20250802174947_AddUserRecipeRelation.Designer.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,374 @@
+﻿// <auto-generated />
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using NutriMatch.Data;
+#nullable disable
+namespace NutriMatch.Migrations
+{
+    [DbContext(typeof(AppDbContext))]
+    [Migration("20250802174947_AddUserRecipeRelation")]
+    partial class AddUserRecipeRelation
+    {
+        protected override void BuildTargetModel(ModelBuilder modelBuilder)
+        {
+#pragma warning disable 612, 618
+            modelBuilder
+                .HasAnnotation("ProductVersion", "9.0.7")
+                .HasAnnotation("Relational:MaxIdentifierLength", 63);
+            NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
+                {
+                    b.Property<string>("Id")
+                        .HasColumnType("text");
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken()
+                        .HasColumnType("text");
+                    b.Property<string>("Name")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<string>("NormalizedName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.HasKey("Id");
+                    b.HasIndex("NormalizedName")
+                        .IsUnique()
+                        .HasDatabaseName("RoleNameIndex");
+                    b.ToTable("AspNetRoles", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<string>("ClaimType")
+                        .HasColumnType("text");
+                    b.Property<string>("ClaimValue")
+                        .HasColumnType("text");
+                    b.Property<string>("RoleId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("RoleId");
+                    b.ToTable("AspNetRoleClaims", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<string>("ClaimType")
+                        .HasColumnType("text");
+                    b.Property<string>("ClaimValue")
+                        .HasColumnType("text");
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("UserId");
+                    b.ToTable("AspNetUserClaims", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
+                {
+                    b.Property<string>("LoginProvider")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("ProviderKey")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("ProviderDisplayName")
+                        .HasColumnType("text");
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("LoginProvider", "ProviderKey");
+                    b.HasIndex("UserId");
+                    b.ToTable("AspNetUserLogins", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
+                {
+                    b.Property<string>("UserId")
+                        .HasColumnType("text");
+                    b.Property<string>("RoleId")
+                        .HasColumnType("text");
+                    b.HasKey("UserId", "RoleId");
+                    b.HasIndex("RoleId");
+                    b.ToTable("AspNetUserRoles", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
+                {
+                    b.Property<string>("UserId")
+                        .HasColumnType("text");
+                    b.Property<string>("LoginProvider")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("Name")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("Value")
+                        .HasColumnType("text");
+                    b.HasKey("UserId", "LoginProvider", "Name");
+                    b.ToTable("AspNetUserTokens", (string)null);
+                });
+            modelBuilder.Entity("NutriMatch.Models.Ingredient", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<float>("Calories")
+                        .HasColumnType("real");
+                    b.Property<float>("Carbs")
+                        .HasColumnType("real");
+                    b.Property<float>("Fat")
+                        .HasColumnType("real");
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<float>("Protein")
+                        .HasColumnType("real");
+                    b.HasKey("Id");
+                    b.ToTable("Ingredients");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Recipe", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<float>("Calories")
+                        .HasColumnType("real");
+                    b.Property<float>("Carbs")
+                        .HasColumnType("real");
+                    b.Property<float>("Fat")
+                        .HasColumnType("real");
+                    b.Property<string>("ImageUrl")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.PrimitiveCollection<string[]>("Instructions")
+                        .HasColumnType("text[]");
+                    b.Property<float>("Protein")
+                        .HasColumnType("real");
+                    b.Property<float>("Rating")
+                        .HasColumnType("real");
+                    b.Property<string>("Title")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("UserId");
+                    b.ToTable("Recipes");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RecipeIngredient", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<int>("IngredientId")
+                        .HasColumnType("integer");
+                    b.Property<float>("Quantity")
+                        .HasColumnType("real");
+                    b.Property<int>("RecipeId")
+                        .HasColumnType("integer");
+                    b.Property<string>("Unit")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("IngredientId");
+                    b.HasIndex("RecipeId");
+                    b.ToTable("RecipeIngredients");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Restaurant", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<string>("Description")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("ImageUrl")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.ToTable("Restaurants");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RestaurantMeal", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<float>("Calories")
+                        .HasColumnType("real");
+                    b.Property<float>("Carbs")
+                        .HasColumnType("real");
+                    b.Property<float>("Fat")
+                        .HasColumnType("real");
+                    b.Property<string>("ItemDescription")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("ItemName")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<float>("Protein")
+                        .HasColumnType("real");
+                    b.Property<int?>("RestaurantId")
+                        .HasColumnType("integer");
+                    b.Property<string>("RestaurantName")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("RestaurantId");
+                    b.ToTable("RestaurantMeals");
+                });
+            modelBuilder.Entity("NutriMatch.Models.User", b =>
+                {
+                    b.Property<string>("Id")
+                        .HasColumnType("text");
+                    b.Property<int>("AccessFailedCount")
+                        .HasColumnType("integer");
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken()
+                        .HasColumnType("text");
+                    b.Property<string>("Email")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<bool>("EmailConfirmed")
+                        .HasColumnType("boolean");
+                    b.Property<bool>("LockoutEnabled")
+                        .HasColumnType("boolean");
+                    b.Property<DateTimeOffset?>("LockoutEnd")
+                        .HasColumnType("timestamp with time zone");
+                    b.Property<string>("NormalizedEmail")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<string>("NormalizedUserName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<string>("PasswordHash")
+                        .HasColumnType("text");
+                    b.Property<string>("PhoneNumber")
+                        .HasColumnType("text");
+                    b.Property<bool>("PhoneNumberConfirmed")
+                        .HasColumnType("boolean");
+                    b.Property<string>("ProfilePictureUrl")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("SecurityStamp")
+                        .HasColumnType("text");
+                    b.Property<bool>("TwoFactorEnabled")
+                        .HasColumnType("boolean");
+                    b.Property<string>("UserName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.HasKey("Id");
+                    b.HasIndex("NormalizedEmail")
+                        .HasDatabaseName("EmailIndex");
+                    b.HasIndex("NormalizedUserName")
+                        .IsUnique()
+                        .HasDatabaseName("UserNameIndex");
+                    b.ToTable("AspNetUsers", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
+                {
+                    b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+                        .WithMany()
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
+                {
+                    b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+                        .WithMany()
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("NutriMatch.Models.Recipe", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", "User")
+                        .WithMany("Recipes")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.Navigation("User");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RecipeIngredient", b =>
+                {
+                    b.HasOne("NutriMatch.Models.Ingredient", "Ingredient")
+                        .WithMany()
+                        .HasForeignKey("IngredientId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.HasOne("NutriMatch.Models.Recipe", null)
+                        .WithMany("RecipeIngredients")
+                        .HasForeignKey("RecipeId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.Navigation("Ingredient");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RestaurantMeal", b =>
+                {
+                    b.HasOne("NutriMatch.Models.Restaurant", "Restaurant")
+                        .WithMany("RestaurantMeals")
+                        .HasForeignKey("RestaurantId");
+                    b.Navigation("Restaurant");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Recipe", b =>
+                {
+                    b.Navigation("RecipeIngredients");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Restaurant", b =>
+                {
+                    b.Navigation("RestaurantMeals");
+                });
+            modelBuilder.Entity("NutriMatch.Models.User", b =>
+                {
+                    b.Navigation("Recipes");
+                });
+#pragma warning restore 612, 618
+        }
+    }
+}
Index: NutriMatch/Migrations/20250802174947_AddUserRecipeRelation.cs
===================================================================
--- NutriMatch/Migrations/20250802174947_AddUserRecipeRelation.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Migrations/20250802174947_AddUserRecipeRelation.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,49 @@
+﻿using Microsoft.EntityFrameworkCore.Migrations;
+#nullable disable
+namespace NutriMatch.Migrations
+{
+    public partial class AddUserRecipeRelation : Migration
+    {
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.AddColumn<string>(
+                name: "UserId",
+                table: "Recipes",
+                type: "text",
+                nullable: false,
+                defaultValue: "");
+            migrationBuilder.AddColumn<string>(
+                name: "ProfilePictureUrl",
+                table: "AspNetUsers",
+                type: "text",
+                nullable: false,
+                defaultValue: "");
+            migrationBuilder.CreateIndex(
+                name: "IX_Recipes_UserId",
+                table: "Recipes",
+                column: "UserId");
+            migrationBuilder.AddForeignKey(
+                name: "FK_Recipes_AspNetUsers_UserId",
+                table: "Recipes",
+                column: "UserId",
+                principalTable: "AspNetUsers",
+                principalColumn: "Id",
+                onDelete: ReferentialAction.Cascade);
+        }
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropForeignKey(
+                name: "FK_Recipes_AspNetUsers_UserId",
+                table: "Recipes");
+            migrationBuilder.DropIndex(
+                name: "IX_Recipes_UserId",
+                table: "Recipes");
+            migrationBuilder.DropColumn(
+                name: "UserId",
+                table: "Recipes");
+            migrationBuilder.DropColumn(
+                name: "ProfilePictureUrl",
+                table: "AspNetUsers");
+        }
+    }
+}
Index: NutriMatch/Migrations/20250804164204_RatingRecipes.Designer.cs
===================================================================
--- NutriMatch/Migrations/20250804164204_RatingRecipes.Designer.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Migrations/20250804164204_RatingRecipes.Designer.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,437 @@
+﻿// <auto-generated />
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using NutriMatch.Data;
+#nullable disable
+namespace NutriMatch.Migrations
+{
+    [DbContext(typeof(AppDbContext))]
+    [Migration("20250804164204_RatingRecipes")]
+    partial class RatingRecipes
+    {
+        protected override void BuildTargetModel(ModelBuilder modelBuilder)
+        {
+#pragma warning disable 612, 618
+            modelBuilder
+                .HasAnnotation("ProductVersion", "9.0.7")
+                .HasAnnotation("Relational:MaxIdentifierLength", 63);
+            NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
+                {
+                    b.Property<string>("Id")
+                        .HasColumnType("text");
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken()
+                        .HasColumnType("text");
+                    b.Property<string>("Name")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<string>("NormalizedName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.HasKey("Id");
+                    b.HasIndex("NormalizedName")
+                        .IsUnique()
+                        .HasDatabaseName("RoleNameIndex");
+                    b.ToTable("AspNetRoles", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<string>("ClaimType")
+                        .HasColumnType("text");
+                    b.Property<string>("ClaimValue")
+                        .HasColumnType("text");
+                    b.Property<string>("RoleId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("RoleId");
+                    b.ToTable("AspNetRoleClaims", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<string>("ClaimType")
+                        .HasColumnType("text");
+                    b.Property<string>("ClaimValue")
+                        .HasColumnType("text");
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("UserId");
+                    b.ToTable("AspNetUserClaims", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
+                {
+                    b.Property<string>("LoginProvider")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("ProviderKey")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("ProviderDisplayName")
+                        .HasColumnType("text");
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("LoginProvider", "ProviderKey");
+                    b.HasIndex("UserId");
+                    b.ToTable("AspNetUserLogins", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
+                {
+                    b.Property<string>("UserId")
+                        .HasColumnType("text");
+                    b.Property<string>("RoleId")
+                        .HasColumnType("text");
+                    b.HasKey("UserId", "RoleId");
+                    b.HasIndex("RoleId");
+                    b.ToTable("AspNetUserRoles", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
+                {
+                    b.Property<string>("UserId")
+                        .HasColumnType("text");
+                    b.Property<string>("LoginProvider")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("Name")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("Value")
+                        .HasColumnType("text");
+                    b.HasKey("UserId", "LoginProvider", "Name");
+                    b.ToTable("AspNetUserTokens", (string)null);
+                });
+            modelBuilder.Entity("NutriMatch.Models.FavoriteRecipe", b =>
+                {
+                    b.Property<string>("UserId")
+                        .HasColumnType("text");
+                    b.Property<int>("RecipeId")
+                        .HasColumnType("integer");
+                    b.HasKey("UserId", "RecipeId");
+                    b.HasIndex("RecipeId");
+                    b.ToTable("FavoriteRecipes");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Ingredient", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<float>("Calories")
+                        .HasColumnType("real");
+                    b.Property<float>("Carbs")
+                        .HasColumnType("real");
+                    b.Property<float>("Fat")
+                        .HasColumnType("real");
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<float>("Protein")
+                        .HasColumnType("real");
+                    b.HasKey("Id");
+                    b.ToTable("Ingredients");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Recipe", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<float>("Calories")
+                        .HasColumnType("real");
+                    b.Property<float>("Carbs")
+                        .HasColumnType("real");
+                    b.Property<float>("Fat")
+                        .HasColumnType("real");
+                    b.Property<string>("ImageUrl")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.PrimitiveCollection<string[]>("Instructions")
+                        .HasColumnType("text[]");
+                    b.Property<float>("Protein")
+                        .HasColumnType("real");
+                    b.Property<float>("Rating")
+                        .HasColumnType("real");
+                    b.Property<string>("Title")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("UserId");
+                    b.ToTable("Recipes");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RecipeIngredient", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<int>("IngredientId")
+                        .HasColumnType("integer");
+                    b.Property<float>("Quantity")
+                        .HasColumnType("real");
+                    b.Property<int>("RecipeId")
+                        .HasColumnType("integer");
+                    b.Property<string>("Unit")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("IngredientId");
+                    b.HasIndex("RecipeId");
+                    b.ToTable("RecipeIngredients");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RecipeRating", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<double>("Rating")
+                        .HasColumnType("double precision");
+                    b.Property<int>("RecipeId")
+                        .HasColumnType("integer");
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("RecipeId");
+                    b.HasIndex("UserId", "RecipeId")
+                        .IsUnique();
+                    b.ToTable("RecipeRatings");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Restaurant", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<string>("Description")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("ImageUrl")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.ToTable("Restaurants");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RestaurantMeal", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<float>("Calories")
+                        .HasColumnType("real");
+                    b.Property<float>("Carbs")
+                        .HasColumnType("real");
+                    b.Property<float>("Fat")
+                        .HasColumnType("real");
+                    b.Property<string>("ItemDescription")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("ItemName")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<float>("Protein")
+                        .HasColumnType("real");
+                    b.Property<int?>("RestaurantId")
+                        .HasColumnType("integer");
+                    b.Property<string>("RestaurantName")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("RestaurantId");
+                    b.ToTable("RestaurantMeals");
+                });
+            modelBuilder.Entity("NutriMatch.Models.User", b =>
+                {
+                    b.Property<string>("Id")
+                        .HasColumnType("text");
+                    b.Property<int>("AccessFailedCount")
+                        .HasColumnType("integer");
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken()
+                        .HasColumnType("text");
+                    b.Property<string>("Email")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<bool>("EmailConfirmed")
+                        .HasColumnType("boolean");
+                    b.Property<bool>("LockoutEnabled")
+                        .HasColumnType("boolean");
+                    b.Property<DateTimeOffset?>("LockoutEnd")
+                        .HasColumnType("timestamp with time zone");
+                    b.Property<string>("NormalizedEmail")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<string>("NormalizedUserName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<string>("PasswordHash")
+                        .HasColumnType("text");
+                    b.Property<string>("PhoneNumber")
+                        .HasColumnType("text");
+                    b.Property<bool>("PhoneNumberConfirmed")
+                        .HasColumnType("boolean");
+                    b.Property<string>("ProfilePictureUrl")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("SecurityStamp")
+                        .HasColumnType("text");
+                    b.Property<bool>("TwoFactorEnabled")
+                        .HasColumnType("boolean");
+                    b.Property<string>("UserName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.HasKey("Id");
+                    b.HasIndex("NormalizedEmail")
+                        .HasDatabaseName("EmailIndex");
+                    b.HasIndex("NormalizedUserName")
+                        .IsUnique()
+                        .HasDatabaseName("UserNameIndex");
+                    b.ToTable("AspNetUsers", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
+                {
+                    b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+                        .WithMany()
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
+                {
+                    b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+                        .WithMany()
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("NutriMatch.Models.FavoriteRecipe", b =>
+                {
+                    b.HasOne("NutriMatch.Models.Recipe", "Recipe")
+                        .WithMany("FavoritedBy")
+                        .HasForeignKey("RecipeId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.HasOne("NutriMatch.Models.User", "User")
+                        .WithMany("FavoriteRecipes")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.Navigation("Recipe");
+                    b.Navigation("User");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Recipe", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", "User")
+                        .WithMany("Recipes")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.Navigation("User");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RecipeIngredient", b =>
+                {
+                    b.HasOne("NutriMatch.Models.Ingredient", "Ingredient")
+                        .WithMany()
+                        .HasForeignKey("IngredientId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.HasOne("NutriMatch.Models.Recipe", null)
+                        .WithMany("RecipeIngredients")
+                        .HasForeignKey("RecipeId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.Navigation("Ingredient");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RecipeRating", b =>
+                {
+                    b.HasOne("NutriMatch.Models.Recipe", "Recipe")
+                        .WithMany("Ratings")
+                        .HasForeignKey("RecipeId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.HasOne("NutriMatch.Models.User", "User")
+                        .WithMany("Ratings")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.Navigation("Recipe");
+                    b.Navigation("User");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RestaurantMeal", b =>
+                {
+                    b.HasOne("NutriMatch.Models.Restaurant", "Restaurant")
+                        .WithMany("RestaurantMeals")
+                        .HasForeignKey("RestaurantId");
+                    b.Navigation("Restaurant");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Recipe", b =>
+                {
+                    b.Navigation("FavoritedBy");
+                    b.Navigation("Ratings");
+                    b.Navigation("RecipeIngredients");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Restaurant", b =>
+                {
+                    b.Navigation("RestaurantMeals");
+                });
+            modelBuilder.Entity("NutriMatch.Models.User", b =>
+                {
+                    b.Navigation("FavoriteRecipes");
+                    b.Navigation("Ratings");
+                    b.Navigation("Recipes");
+                });
+#pragma warning restore 612, 618
+        }
+    }
+}
Index: NutriMatch/Migrations/20250804164204_RatingRecipes.cs
===================================================================
--- NutriMatch/Migrations/20250804164204_RatingRecipes.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Migrations/20250804164204_RatingRecipes.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,81 @@
+﻿using Microsoft.EntityFrameworkCore.Migrations;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+#nullable disable
+namespace NutriMatch.Migrations
+{
+    public partial class RatingRecipes : Migration
+    {
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.CreateTable(
+                name: "FavoriteRecipes",
+                columns: table => new
+                {
+                    UserId = table.Column<string>(type: "text", nullable: false),
+                    RecipeId = table.Column<int>(type: "integer", nullable: false)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_FavoriteRecipes", x => new { x.UserId, x.RecipeId });
+                    table.ForeignKey(
+                        name: "FK_FavoriteRecipes_AspNetUsers_UserId",
+                        column: x => x.UserId,
+                        principalTable: "AspNetUsers",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                    table.ForeignKey(
+                        name: "FK_FavoriteRecipes_Recipes_RecipeId",
+                        column: x => x.RecipeId,
+                        principalTable: "Recipes",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                });
+            migrationBuilder.CreateTable(
+                name: "RecipeRatings",
+                columns: table => new
+                {
+                    Id = table.Column<int>(type: "integer", nullable: false)
+                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+                    UserId = table.Column<string>(type: "text", nullable: false),
+                    RecipeId = table.Column<int>(type: "integer", nullable: false),
+                    Rating = table.Column<double>(type: "double precision", nullable: false)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_RecipeRatings", x => x.Id);
+                    table.ForeignKey(
+                        name: "FK_RecipeRatings_AspNetUsers_UserId",
+                        column: x => x.UserId,
+                        principalTable: "AspNetUsers",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                    table.ForeignKey(
+                        name: "FK_RecipeRatings_Recipes_RecipeId",
+                        column: x => x.RecipeId,
+                        principalTable: "Recipes",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                });
+            migrationBuilder.CreateIndex(
+                name: "IX_FavoriteRecipes_RecipeId",
+                table: "FavoriteRecipes",
+                column: "RecipeId");
+            migrationBuilder.CreateIndex(
+                name: "IX_RecipeRatings_RecipeId",
+                table: "RecipeRatings",
+                column: "RecipeId");
+            migrationBuilder.CreateIndex(
+                name: "IX_RecipeRatings_UserId_RecipeId",
+                table: "RecipeRatings",
+                columns: new[] { "UserId", "RecipeId" },
+                unique: true);
+        }
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropTable(
+                name: "FavoriteRecipes");
+            migrationBuilder.DropTable(
+                name: "RecipeRatings");
+        }
+    }
+}
Index: NutriMatch/Migrations/20250805200628_RecipeModelChange.Designer.cs
===================================================================
--- NutriMatch/Migrations/20250805200628_RecipeModelChange.Designer.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Migrations/20250805200628_RecipeModelChange.Designer.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,435 @@
+﻿// <auto-generated />
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using NutriMatch.Data;
+#nullable disable
+namespace NutriMatch.Migrations
+{
+    [DbContext(typeof(AppDbContext))]
+    [Migration("20250805200628_RecipeModelChange")]
+    partial class RecipeModelChange
+    {
+        protected override void BuildTargetModel(ModelBuilder modelBuilder)
+        {
+#pragma warning disable 612, 618
+            modelBuilder
+                .HasAnnotation("ProductVersion", "9.0.7")
+                .HasAnnotation("Relational:MaxIdentifierLength", 63);
+            NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
+                {
+                    b.Property<string>("Id")
+                        .HasColumnType("text");
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken()
+                        .HasColumnType("text");
+                    b.Property<string>("Name")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<string>("NormalizedName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.HasKey("Id");
+                    b.HasIndex("NormalizedName")
+                        .IsUnique()
+                        .HasDatabaseName("RoleNameIndex");
+                    b.ToTable("AspNetRoles", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<string>("ClaimType")
+                        .HasColumnType("text");
+                    b.Property<string>("ClaimValue")
+                        .HasColumnType("text");
+                    b.Property<string>("RoleId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("RoleId");
+                    b.ToTable("AspNetRoleClaims", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<string>("ClaimType")
+                        .HasColumnType("text");
+                    b.Property<string>("ClaimValue")
+                        .HasColumnType("text");
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("UserId");
+                    b.ToTable("AspNetUserClaims", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
+                {
+                    b.Property<string>("LoginProvider")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("ProviderKey")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("ProviderDisplayName")
+                        .HasColumnType("text");
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("LoginProvider", "ProviderKey");
+                    b.HasIndex("UserId");
+                    b.ToTable("AspNetUserLogins", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
+                {
+                    b.Property<string>("UserId")
+                        .HasColumnType("text");
+                    b.Property<string>("RoleId")
+                        .HasColumnType("text");
+                    b.HasKey("UserId", "RoleId");
+                    b.HasIndex("RoleId");
+                    b.ToTable("AspNetUserRoles", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
+                {
+                    b.Property<string>("UserId")
+                        .HasColumnType("text");
+                    b.Property<string>("LoginProvider")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("Name")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("Value")
+                        .HasColumnType("text");
+                    b.HasKey("UserId", "LoginProvider", "Name");
+                    b.ToTable("AspNetUserTokens", (string)null);
+                });
+            modelBuilder.Entity("NutriMatch.Models.FavoriteRecipe", b =>
+                {
+                    b.Property<string>("UserId")
+                        .HasColumnType("text");
+                    b.Property<int>("RecipeId")
+                        .HasColumnType("integer");
+                    b.HasKey("UserId", "RecipeId");
+                    b.HasIndex("RecipeId");
+                    b.ToTable("FavoriteRecipes");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Ingredient", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<float>("Calories")
+                        .HasColumnType("real");
+                    b.Property<float>("Carbs")
+                        .HasColumnType("real");
+                    b.Property<float>("Fat")
+                        .HasColumnType("real");
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<float>("Protein")
+                        .HasColumnType("real");
+                    b.HasKey("Id");
+                    b.ToTable("Ingredients");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Recipe", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<float>("Calories")
+                        .HasColumnType("real");
+                    b.Property<float>("Carbs")
+                        .HasColumnType("real");
+                    b.Property<float>("Fat")
+                        .HasColumnType("real");
+                    b.Property<string>("ImageUrl")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.PrimitiveCollection<string[]>("Instructions")
+                        .HasColumnType("text[]");
+                    b.Property<float>("Protein")
+                        .HasColumnType("real");
+                    b.Property<string>("Title")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("UserId");
+                    b.ToTable("Recipes");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RecipeIngredient", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<int>("IngredientId")
+                        .HasColumnType("integer");
+                    b.Property<float>("Quantity")
+                        .HasColumnType("real");
+                    b.Property<int>("RecipeId")
+                        .HasColumnType("integer");
+                    b.Property<string>("Unit")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("IngredientId");
+                    b.HasIndex("RecipeId");
+                    b.ToTable("RecipeIngredients");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RecipeRating", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<double>("Rating")
+                        .HasColumnType("double precision");
+                    b.Property<int>("RecipeId")
+                        .HasColumnType("integer");
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("RecipeId");
+                    b.HasIndex("UserId", "RecipeId")
+                        .IsUnique();
+                    b.ToTable("RecipeRatings");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Restaurant", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<string>("Description")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("ImageUrl")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.ToTable("Restaurants");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RestaurantMeal", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<float>("Calories")
+                        .HasColumnType("real");
+                    b.Property<float>("Carbs")
+                        .HasColumnType("real");
+                    b.Property<float>("Fat")
+                        .HasColumnType("real");
+                    b.Property<string>("ItemDescription")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("ItemName")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<float>("Protein")
+                        .HasColumnType("real");
+                    b.Property<int?>("RestaurantId")
+                        .HasColumnType("integer");
+                    b.Property<string>("RestaurantName")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("RestaurantId");
+                    b.ToTable("RestaurantMeals");
+                });
+            modelBuilder.Entity("NutriMatch.Models.User", b =>
+                {
+                    b.Property<string>("Id")
+                        .HasColumnType("text");
+                    b.Property<int>("AccessFailedCount")
+                        .HasColumnType("integer");
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken()
+                        .HasColumnType("text");
+                    b.Property<string>("Email")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<bool>("EmailConfirmed")
+                        .HasColumnType("boolean");
+                    b.Property<bool>("LockoutEnabled")
+                        .HasColumnType("boolean");
+                    b.Property<DateTimeOffset?>("LockoutEnd")
+                        .HasColumnType("timestamp with time zone");
+                    b.Property<string>("NormalizedEmail")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<string>("NormalizedUserName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<string>("PasswordHash")
+                        .HasColumnType("text");
+                    b.Property<string>("PhoneNumber")
+                        .HasColumnType("text");
+                    b.Property<bool>("PhoneNumberConfirmed")
+                        .HasColumnType("boolean");
+                    b.Property<string>("ProfilePictureUrl")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("SecurityStamp")
+                        .HasColumnType("text");
+                    b.Property<bool>("TwoFactorEnabled")
+                        .HasColumnType("boolean");
+                    b.Property<string>("UserName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.HasKey("Id");
+                    b.HasIndex("NormalizedEmail")
+                        .HasDatabaseName("EmailIndex");
+                    b.HasIndex("NormalizedUserName")
+                        .IsUnique()
+                        .HasDatabaseName("UserNameIndex");
+                    b.ToTable("AspNetUsers", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
+                {
+                    b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+                        .WithMany()
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
+                {
+                    b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+                        .WithMany()
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("NutriMatch.Models.FavoriteRecipe", b =>
+                {
+                    b.HasOne("NutriMatch.Models.Recipe", "Recipe")
+                        .WithMany("FavoritedBy")
+                        .HasForeignKey("RecipeId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.HasOne("NutriMatch.Models.User", "User")
+                        .WithMany("FavoriteRecipes")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.Navigation("Recipe");
+                    b.Navigation("User");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Recipe", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", "User")
+                        .WithMany("Recipes")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.Navigation("User");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RecipeIngredient", b =>
+                {
+                    b.HasOne("NutriMatch.Models.Ingredient", "Ingredient")
+                        .WithMany()
+                        .HasForeignKey("IngredientId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.HasOne("NutriMatch.Models.Recipe", null)
+                        .WithMany("RecipeIngredients")
+                        .HasForeignKey("RecipeId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.Navigation("Ingredient");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RecipeRating", b =>
+                {
+                    b.HasOne("NutriMatch.Models.Recipe", "Recipe")
+                        .WithMany("Ratings")
+                        .HasForeignKey("RecipeId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.HasOne("NutriMatch.Models.User", "User")
+                        .WithMany("Ratings")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.Navigation("Recipe");
+                    b.Navigation("User");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RestaurantMeal", b =>
+                {
+                    b.HasOne("NutriMatch.Models.Restaurant", "Restaurant")
+                        .WithMany("RestaurantMeals")
+                        .HasForeignKey("RestaurantId");
+                    b.Navigation("Restaurant");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Recipe", b =>
+                {
+                    b.Navigation("FavoritedBy");
+                    b.Navigation("Ratings");
+                    b.Navigation("RecipeIngredients");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Restaurant", b =>
+                {
+                    b.Navigation("RestaurantMeals");
+                });
+            modelBuilder.Entity("NutriMatch.Models.User", b =>
+                {
+                    b.Navigation("FavoriteRecipes");
+                    b.Navigation("Ratings");
+                    b.Navigation("Recipes");
+                });
+#pragma warning restore 612, 618
+        }
+    }
+}
Index: NutriMatch/Migrations/20250805200628_RecipeModelChange.cs
===================================================================
--- NutriMatch/Migrations/20250805200628_RecipeModelChange.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Migrations/20250805200628_RecipeModelChange.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,23 @@
+﻿using Microsoft.EntityFrameworkCore.Migrations;
+#nullable disable
+namespace NutriMatch.Migrations
+{
+    public partial class RecipeModelChange : Migration
+    {
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropColumn(
+                name: "Rating",
+                table: "Recipes");
+        }
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.AddColumn<float>(
+                name: "Rating",
+                table: "Recipes",
+                type: "real",
+                nullable: false,
+                defaultValue: 0f);
+        }
+    }
+}
Index: NutriMatch/Migrations/20250806174559_RecipeApproval.Designer.cs
===================================================================
--- NutriMatch/Migrations/20250806174559_RecipeApproval.Designer.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Migrations/20250806174559_RecipeApproval.Designer.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,439 @@
+﻿// <auto-generated />
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using NutriMatch.Data;
+#nullable disable
+namespace NutriMatch.Migrations
+{
+    [DbContext(typeof(AppDbContext))]
+    [Migration("20250806174559_RecipeApproval")]
+    partial class RecipeApproval
+    {
+        protected override void BuildTargetModel(ModelBuilder modelBuilder)
+        {
+#pragma warning disable 612, 618
+            modelBuilder
+                .HasAnnotation("ProductVersion", "9.0.7")
+                .HasAnnotation("Relational:MaxIdentifierLength", 63);
+            NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
+                {
+                    b.Property<string>("Id")
+                        .HasColumnType("text");
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken()
+                        .HasColumnType("text");
+                    b.Property<string>("Name")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<string>("NormalizedName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.HasKey("Id");
+                    b.HasIndex("NormalizedName")
+                        .IsUnique()
+                        .HasDatabaseName("RoleNameIndex");
+                    b.ToTable("AspNetRoles", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<string>("ClaimType")
+                        .HasColumnType("text");
+                    b.Property<string>("ClaimValue")
+                        .HasColumnType("text");
+                    b.Property<string>("RoleId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("RoleId");
+                    b.ToTable("AspNetRoleClaims", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<string>("ClaimType")
+                        .HasColumnType("text");
+                    b.Property<string>("ClaimValue")
+                        .HasColumnType("text");
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("UserId");
+                    b.ToTable("AspNetUserClaims", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
+                {
+                    b.Property<string>("LoginProvider")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("ProviderKey")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("ProviderDisplayName")
+                        .HasColumnType("text");
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("LoginProvider", "ProviderKey");
+                    b.HasIndex("UserId");
+                    b.ToTable("AspNetUserLogins", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
+                {
+                    b.Property<string>("UserId")
+                        .HasColumnType("text");
+                    b.Property<string>("RoleId")
+                        .HasColumnType("text");
+                    b.HasKey("UserId", "RoleId");
+                    b.HasIndex("RoleId");
+                    b.ToTable("AspNetUserRoles", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
+                {
+                    b.Property<string>("UserId")
+                        .HasColumnType("text");
+                    b.Property<string>("LoginProvider")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("Name")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("Value")
+                        .HasColumnType("text");
+                    b.HasKey("UserId", "LoginProvider", "Name");
+                    b.ToTable("AspNetUserTokens", (string)null);
+                });
+            modelBuilder.Entity("NutriMatch.Models.FavoriteRecipe", b =>
+                {
+                    b.Property<string>("UserId")
+                        .HasColumnType("text");
+                    b.Property<int>("RecipeId")
+                        .HasColumnType("integer");
+                    b.HasKey("UserId", "RecipeId");
+                    b.HasIndex("RecipeId");
+                    b.ToTable("FavoriteRecipes");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Ingredient", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<float>("Calories")
+                        .HasColumnType("real");
+                    b.Property<float>("Carbs")
+                        .HasColumnType("real");
+                    b.Property<float>("Fat")
+                        .HasColumnType("real");
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<float>("Protein")
+                        .HasColumnType("real");
+                    b.HasKey("Id");
+                    b.ToTable("Ingredients");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Recipe", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<float>("Calories")
+                        .HasColumnType("real");
+                    b.Property<float>("Carbs")
+                        .HasColumnType("real");
+                    b.Property<DateTime>("CreatedAt")
+                        .HasColumnType("timestamp with time zone");
+                    b.Property<float>("Fat")
+                        .HasColumnType("real");
+                    b.Property<string>("ImageUrl")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.PrimitiveCollection<string[]>("Instructions")
+                        .HasColumnType("text[]");
+                    b.Property<bool>("IsApproved")
+                        .HasColumnType("boolean");
+                    b.Property<float>("Protein")
+                        .HasColumnType("real");
+                    b.Property<string>("Title")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("UserId");
+                    b.ToTable("Recipes");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RecipeIngredient", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<int>("IngredientId")
+                        .HasColumnType("integer");
+                    b.Property<float>("Quantity")
+                        .HasColumnType("real");
+                    b.Property<int>("RecipeId")
+                        .HasColumnType("integer");
+                    b.Property<string>("Unit")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("IngredientId");
+                    b.HasIndex("RecipeId");
+                    b.ToTable("RecipeIngredients");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RecipeRating", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<double>("Rating")
+                        .HasColumnType("double precision");
+                    b.Property<int>("RecipeId")
+                        .HasColumnType("integer");
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("RecipeId");
+                    b.HasIndex("UserId", "RecipeId")
+                        .IsUnique();
+                    b.ToTable("RecipeRatings");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Restaurant", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<string>("Description")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("ImageUrl")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.ToTable("Restaurants");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RestaurantMeal", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<float>("Calories")
+                        .HasColumnType("real");
+                    b.Property<float>("Carbs")
+                        .HasColumnType("real");
+                    b.Property<float>("Fat")
+                        .HasColumnType("real");
+                    b.Property<string>("ItemDescription")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("ItemName")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<float>("Protein")
+                        .HasColumnType("real");
+                    b.Property<int?>("RestaurantId")
+                        .HasColumnType("integer");
+                    b.Property<string>("RestaurantName")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("RestaurantId");
+                    b.ToTable("RestaurantMeals");
+                });
+            modelBuilder.Entity("NutriMatch.Models.User", b =>
+                {
+                    b.Property<string>("Id")
+                        .HasColumnType("text");
+                    b.Property<int>("AccessFailedCount")
+                        .HasColumnType("integer");
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken()
+                        .HasColumnType("text");
+                    b.Property<string>("Email")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<bool>("EmailConfirmed")
+                        .HasColumnType("boolean");
+                    b.Property<bool>("LockoutEnabled")
+                        .HasColumnType("boolean");
+                    b.Property<DateTimeOffset?>("LockoutEnd")
+                        .HasColumnType("timestamp with time zone");
+                    b.Property<string>("NormalizedEmail")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<string>("NormalizedUserName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<string>("PasswordHash")
+                        .HasColumnType("text");
+                    b.Property<string>("PhoneNumber")
+                        .HasColumnType("text");
+                    b.Property<bool>("PhoneNumberConfirmed")
+                        .HasColumnType("boolean");
+                    b.Property<string>("ProfilePictureUrl")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("SecurityStamp")
+                        .HasColumnType("text");
+                    b.Property<bool>("TwoFactorEnabled")
+                        .HasColumnType("boolean");
+                    b.Property<string>("UserName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.HasKey("Id");
+                    b.HasIndex("NormalizedEmail")
+                        .HasDatabaseName("EmailIndex");
+                    b.HasIndex("NormalizedUserName")
+                        .IsUnique()
+                        .HasDatabaseName("UserNameIndex");
+                    b.ToTable("AspNetUsers", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
+                {
+                    b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+                        .WithMany()
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
+                {
+                    b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+                        .WithMany()
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("NutriMatch.Models.FavoriteRecipe", b =>
+                {
+                    b.HasOne("NutriMatch.Models.Recipe", "Recipe")
+                        .WithMany("FavoritedBy")
+                        .HasForeignKey("RecipeId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.HasOne("NutriMatch.Models.User", "User")
+                        .WithMany("FavoriteRecipes")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.Navigation("Recipe");
+                    b.Navigation("User");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Recipe", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", "User")
+                        .WithMany("Recipes")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.Navigation("User");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RecipeIngredient", b =>
+                {
+                    b.HasOne("NutriMatch.Models.Ingredient", "Ingredient")
+                        .WithMany()
+                        .HasForeignKey("IngredientId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.HasOne("NutriMatch.Models.Recipe", null)
+                        .WithMany("RecipeIngredients")
+                        .HasForeignKey("RecipeId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.Navigation("Ingredient");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RecipeRating", b =>
+                {
+                    b.HasOne("NutriMatch.Models.Recipe", "Recipe")
+                        .WithMany("Ratings")
+                        .HasForeignKey("RecipeId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.HasOne("NutriMatch.Models.User", "User")
+                        .WithMany("Ratings")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.Navigation("Recipe");
+                    b.Navigation("User");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RestaurantMeal", b =>
+                {
+                    b.HasOne("NutriMatch.Models.Restaurant", "Restaurant")
+                        .WithMany("RestaurantMeals")
+                        .HasForeignKey("RestaurantId");
+                    b.Navigation("Restaurant");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Recipe", b =>
+                {
+                    b.Navigation("FavoritedBy");
+                    b.Navigation("Ratings");
+                    b.Navigation("RecipeIngredients");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Restaurant", b =>
+                {
+                    b.Navigation("RestaurantMeals");
+                });
+            modelBuilder.Entity("NutriMatch.Models.User", b =>
+                {
+                    b.Navigation("FavoriteRecipes");
+                    b.Navigation("Ratings");
+                    b.Navigation("Recipes");
+                });
+#pragma warning restore 612, 618
+        }
+    }
+}
Index: NutriMatch/Migrations/20250806174559_RecipeApproval.cs
===================================================================
--- NutriMatch/Migrations/20250806174559_RecipeApproval.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Migrations/20250806174559_RecipeApproval.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,33 @@
+﻿using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+#nullable disable
+namespace NutriMatch.Migrations
+{
+    public partial class RecipeApproval : Migration
+    {
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.AddColumn<DateTime>(
+                name: "CreatedAt",
+                table: "Recipes",
+                type: "timestamp with time zone",
+                nullable: false,
+                defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
+            migrationBuilder.AddColumn<bool>(
+                name: "IsApproved",
+                table: "Recipes",
+                type: "boolean",
+                nullable: false,
+                defaultValue: false);
+        }
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropColumn(
+                name: "CreatedAt",
+                table: "Recipes");
+            migrationBuilder.DropColumn(
+                name: "IsApproved",
+                table: "Recipes");
+        }
+    }
+}
Index: NutriMatch/Migrations/AppDbContextModelSnapshot.cs
===================================================================
--- NutriMatch/Migrations/AppDbContextModelSnapshot.cs	(revision a8860663d8380fb13055bfa6006477787df4824f)
+++ NutriMatch/Migrations/AppDbContextModelSnapshot.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -1,3 +1,4 @@
 ﻿// <auto-generated />
+using System;
 using Microsoft.EntityFrameworkCore;
 using Microsoft.EntityFrameworkCore.Infrastructure;
@@ -15,7 +16,112 @@
 #pragma warning disable 612, 618
             modelBuilder
-                .HasAnnotation("ProductVersion", "9.0.5")
+                .HasAnnotation("ProductVersion", "9.0.7")
                 .HasAnnotation("Relational:MaxIdentifierLength", 63);
             NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
+                {
+                    b.Property<string>("Id")
+                        .HasColumnType("text");
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken()
+                        .HasColumnType("text");
+                    b.Property<string>("Name")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<string>("NormalizedName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.HasKey("Id");
+                    b.HasIndex("NormalizedName")
+                        .IsUnique()
+                        .HasDatabaseName("RoleNameIndex");
+                    b.ToTable("AspNetRoles", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<string>("ClaimType")
+                        .HasColumnType("text");
+                    b.Property<string>("ClaimValue")
+                        .HasColumnType("text");
+                    b.Property<string>("RoleId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("RoleId");
+                    b.ToTable("AspNetRoleClaims", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<string>("ClaimType")
+                        .HasColumnType("text");
+                    b.Property<string>("ClaimValue")
+                        .HasColumnType("text");
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("UserId");
+                    b.ToTable("AspNetUserClaims", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
+                {
+                    b.Property<string>("LoginProvider")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("ProviderKey")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("ProviderDisplayName")
+                        .HasColumnType("text");
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("LoginProvider", "ProviderKey");
+                    b.HasIndex("UserId");
+                    b.ToTable("AspNetUserLogins", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
+                {
+                    b.Property<string>("UserId")
+                        .HasColumnType("text");
+                    b.Property<string>("RoleId")
+                        .HasColumnType("text");
+                    b.HasKey("UserId", "RoleId");
+                    b.HasIndex("RoleId");
+                    b.ToTable("AspNetUserRoles", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
+                {
+                    b.Property<string>("UserId")
+                        .HasColumnType("text");
+                    b.Property<string>("LoginProvider")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("Name")
+                        .HasMaxLength(128)
+                        .HasColumnType("character varying(128)");
+                    b.Property<string>("Value")
+                        .HasColumnType("text");
+                    b.HasKey("UserId", "LoginProvider", "Name");
+                    b.ToTable("AspNetUserTokens", (string)null);
+                });
+            modelBuilder.Entity("NutriMatch.Models.FavoriteRecipe", b =>
+                {
+                    b.Property<string>("UserId")
+                        .HasColumnType("text");
+                    b.Property<int>("RecipeId")
+                        .HasColumnType("integer");
+                    b.HasKey("UserId", "RecipeId");
+                    b.HasIndex("RecipeId");
+                    b.ToTable("FavoriteRecipes");
+                });
             modelBuilder.Entity("NutriMatch.Models.Ingredient", b =>
                 {
@@ -48,4 +154,6 @@
                     b.Property<float>("Carbs")
                         .HasColumnType("real");
+                    b.Property<DateTime>("CreatedAt")
+                        .HasColumnType("timestamp with time zone");
                     b.Property<float>("Fat")
                         .HasColumnType("real");
@@ -55,12 +163,16 @@
                     b.PrimitiveCollection<string[]>("Instructions")
                         .HasColumnType("text[]");
+                    b.Property<bool>("IsApproved")
+                        .HasColumnType("boolean");
                     b.Property<float>("Protein")
                         .HasColumnType("real");
-                    b.Property<float>("Rating")
-                        .HasColumnType("real");
                     b.Property<string>("Title")
                         .IsRequired()
                         .HasColumnType("text");
-                    b.HasKey("Id");
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("UserId");
                     b.ToTable("Recipes");
                 });
@@ -85,4 +197,23 @@
                     b.ToTable("RecipeIngredients");
                 });
+            modelBuilder.Entity("NutriMatch.Models.RecipeRating", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer");
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+                    b.Property<double>("Rating")
+                        .HasColumnType("double precision");
+                    b.Property<int>("RecipeId")
+                        .HasColumnType("integer");
+                    b.Property<string>("UserId")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.HasKey("Id");
+                    b.HasIndex("RecipeId");
+                    b.HasIndex("UserId", "RecipeId")
+                        .IsUnique();
+                    b.ToTable("RecipeRatings");
+                });
             modelBuilder.Entity("NutriMatch.Models.Restaurant", b =>
                 {
@@ -131,4 +262,121 @@
                     b.HasIndex("RestaurantId");
                     b.ToTable("RestaurantMeals");
+                });
+            modelBuilder.Entity("NutriMatch.Models.User", b =>
+                {
+                    b.Property<string>("Id")
+                        .HasColumnType("text");
+                    b.Property<int>("AccessFailedCount")
+                        .HasColumnType("integer");
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken()
+                        .HasColumnType("text");
+                    b.Property<string>("Email")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<bool>("EmailConfirmed")
+                        .HasColumnType("boolean");
+                    b.Property<bool>("LockoutEnabled")
+                        .HasColumnType("boolean");
+                    b.Property<DateTimeOffset?>("LockoutEnd")
+                        .HasColumnType("timestamp with time zone");
+                    b.Property<string>("NormalizedEmail")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<string>("NormalizedUserName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.Property<string>("PasswordHash")
+                        .HasColumnType("text");
+                    b.Property<string>("PhoneNumber")
+                        .HasColumnType("text");
+                    b.Property<bool>("PhoneNumberConfirmed")
+                        .HasColumnType("boolean");
+                    b.Property<string>("ProfilePictureUrl")
+                        .IsRequired()
+                        .HasColumnType("text");
+                    b.Property<string>("SecurityStamp")
+                        .HasColumnType("text");
+                    b.Property<bool>("TwoFactorEnabled")
+                        .HasColumnType("boolean");
+                    b.Property<string>("UserName")
+                        .HasMaxLength(256)
+                        .HasColumnType("character varying(256)");
+                    b.HasKey("Id");
+                    b.HasIndex("NormalizedEmail")
+                        .HasDatabaseName("EmailIndex");
+                    b.HasIndex("NormalizedUserName")
+                        .IsUnique()
+                        .HasDatabaseName("UserNameIndex");
+                    b.ToTable("AspNetUsers", (string)null);
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
+                {
+                    b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+                        .WithMany()
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
+                {
+                    b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+                        .WithMany()
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", null)
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+            modelBuilder.Entity("NutriMatch.Models.FavoriteRecipe", b =>
+                {
+                    b.HasOne("NutriMatch.Models.Recipe", "Recipe")
+                        .WithMany("FavoritedBy")
+                        .HasForeignKey("RecipeId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.HasOne("NutriMatch.Models.User", "User")
+                        .WithMany("FavoriteRecipes")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.Navigation("Recipe");
+                    b.Navigation("User");
+                });
+            modelBuilder.Entity("NutriMatch.Models.Recipe", b =>
+                {
+                    b.HasOne("NutriMatch.Models.User", "User")
+                        .WithMany("Recipes")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.Navigation("User");
                 });
             modelBuilder.Entity("NutriMatch.Models.RecipeIngredient", b =>
@@ -145,4 +393,19 @@
                         .IsRequired();
                     b.Navigation("Ingredient");
+                });
+            modelBuilder.Entity("NutriMatch.Models.RecipeRating", b =>
+                {
+                    b.HasOne("NutriMatch.Models.Recipe", "Recipe")
+                        .WithMany("Ratings")
+                        .HasForeignKey("RecipeId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.HasOne("NutriMatch.Models.User", "User")
+                        .WithMany("Ratings")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                    b.Navigation("Recipe");
+                    b.Navigation("User");
                 });
             modelBuilder.Entity("NutriMatch.Models.RestaurantMeal", b =>
@@ -155,4 +418,6 @@
             modelBuilder.Entity("NutriMatch.Models.Recipe", b =>
                 {
+                    b.Navigation("FavoritedBy");
+                    b.Navigation("Ratings");
                     b.Navigation("RecipeIngredients");
                 });
@@ -160,4 +425,10 @@
                 {
                     b.Navigation("RestaurantMeals");
+                });
+            modelBuilder.Entity("NutriMatch.Models.User", b =>
+                {
+                    b.Navigation("FavoriteRecipes");
+                    b.Navigation("Ratings");
+                    b.Navigation("Recipes");
                 });
 #pragma warning restore 612, 618
Index: NutriMatch/Models/FavoriteRecipe.cs
===================================================================
--- NutriMatch/Models/FavoriteRecipe.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Models/FavoriteRecipe.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,10 @@
+namespace NutriMatch.Models
+{
+    public class FavoriteRecipe
+    {
+        public string UserId { get; set; }
+        public User User { get; set; }
+         public int RecipeId { get; set; }
+        public Recipe Recipe { get; set; }
+    }
+}
Index: NutriMatch/Models/Recipe.cs
===================================================================
--- NutriMatch/Models/Recipe.cs	(revision a8860663d8380fb13055bfa6006477787df4824f)
+++ NutriMatch/Models/Recipe.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -2,4 +2,5 @@
 using System.Collections.Generic;
 using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
 using System.Linq;
 using System.Threading.Tasks;
@@ -15,7 +16,8 @@
         public String[]? Instructions { get; set; }
         [ValidateNever]
-        public float Rating { get; set; }
+        [NotMapped]
+        public double Rating { get; set; } 
         [ValidateNever]
-        public virtual List<RecipeIngredient> RecipeIngredients { get; set; }   
+        public virtual List<RecipeIngredient> RecipeIngredients { get; set; }
         [ValidateNever]
         public float Calories { get; set; }
@@ -27,7 +29,16 @@
         public float Fat { get; set; }
         [ValidateNever]
+        public String ImageUrl { get; set; }
+        public DateTime CreatedAt { get; set; } = DateTime.Now.ToUniversalTime();
+        public bool IsApproved { get; set; } = false;
 
-        public String ImageUrl { get; set; } 
-        
+        [ValidateNever]
+        public String UserId { get; set; }
+        [ValidateNever]
+        public virtual User User { get; set; }
+        [ValidateNever]
+        public ICollection<FavoriteRecipe> FavoritedBy { get; set; }
+        [ValidateNever]
+        public ICollection<RecipeRating> Ratings { get; set; }
     }
 }
Index: NutriMatch/Models/RecipeRating.cs
===================================================================
--- NutriMatch/Models/RecipeRating.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Models/RecipeRating.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,19 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace NutriMatch.Models
+{
+    public class RecipeRating
+    {
+        public int Id { get; set; }
+
+        public string UserId { get; set; }
+        public User User { get; set; }
+
+        public int RecipeId { get; set; }
+        public Recipe Recipe { get; set; }
+
+        [Range(1.0, 5.0)]
+        public double Rating { get; set; }
+    }
+
+}
Index: NutriMatch/Models/User.cs
===================================================================
--- NutriMatch/Models/User.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Models/User.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Identity;
+
+namespace NutriMatch.Models
+{
+    public class User : IdentityUser
+    {
+        public virtual ICollection<Recipe> Recipes { get; set; }
+
+        public String ProfilePictureUrl { get; set; }
+        public ICollection<FavoriteRecipe> FavoriteRecipes { get; set; }
+        public ICollection<RecipeRating> Ratings { get; set; }
+        
+    }
+}
Index: NutriMatch/NutriMatch.csproj
===================================================================
--- NutriMatch/NutriMatch.csproj	(revision a8860663d8380fb13055bfa6006477787df4824f)
+++ NutriMatch/NutriMatch.csproj	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -8,4 +8,7 @@
 
   <ItemGroup>
+    <PackageReference Include="Microsoft.AspNet.Identity.EntityFramework" Version="2.2.4" />
+    <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.7" />
+    <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="9.0.7" />
     <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.5">
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Index: NutriMatch/Program.cs
===================================================================
--- NutriMatch/Program.cs	(revision a8860663d8380fb13055bfa6006477787df4824f)
+++ NutriMatch/Program.cs	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -1,8 +1,17 @@
 using Microsoft.EntityFrameworkCore;
 using NutriMatch.Data;
+using NutriMatch.Models;
+using Microsoft.AspNetCore.Identity;
 var builder = WebApplication.CreateBuilder(args);
 builder.Services.AddControllersWithViews();
+builder.Services.AddRazorPages();
 builder.Services.AddDbContext<AppDbContext>(options =>
     options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));
+builder.Services.AddDefaultIdentity<User>(options =>
+{
+    options.SignIn.RequireConfirmedAccount = false;
+})
+.AddRoles<IdentityRole>()
+.AddEntityFrameworkStores<AppDbContext>();
 var app = builder.Build();
 if (!app.Environment.IsDevelopment())
@@ -13,5 +22,7 @@
 app.UseHttpsRedirection();
 app.UseRouting();
+app.UseAuthentication();
 app.UseAuthorization();
+app.MapRazorPages();
 app.MapStaticAssets();
 app.MapControllerRoute(
@@ -19,3 +30,15 @@
     pattern: "{controller=Home}/{action=Index}/{id?}")
     .WithStaticAssets();
+using (var scope = app.Services.CreateScope())
+{
+    var services = scope.ServiceProvider;
+    try
+    {
+        await DbInitializer.SeedRolesAsync(services);
+    }
+    catch (Exception ex)
+    {
+        Console.WriteLine("Error during seeding: " + ex.Message);
+    }
+}
 app.Run();
Index: NutriMatch/ScaffoldingReadMe.txt
===================================================================
--- NutriMatch/ScaffoldingReadMe.txt	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/ScaffoldingReadMe.txt	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,2 @@
+﻿Support for ASP.NET Core Identity was added to your project.
+For setup and configuration information, see https://go.microsoft.com/fwlink/?linkid=2116645.
Index: NutriMatch/Views/Admin/Index.cshtml
===================================================================
--- NutriMatch/Views/Admin/Index.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Views/Admin/Index.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,950 @@
+@model List<NutriMatch.Models.Recipe>
+@{
+    Layout = "_Layout";
+}
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <link href="~/css/RecipeIndex.css" rel="stylesheet">
+    <title>NutriMatch - Admin Panel</title>
+    <style>
+        .admin-header {
+            background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
+            border-radius: 12px;
+            padding: 2rem;
+            border: 1px solid #e2e8f0;
+            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
+        }
+        .admin-title {
+            font-size: 2rem;
+            font-weight: 700;
+            color: #1f2937;
+            margin: 0;
+        }
+        .admin-subtitle {
+            font-size: 1.1rem;
+            margin: 0;
+            margin-top: 0.5rem;
+        }
+        .admin-stats .badge {
+            padding: 0.5rem 1rem;
+            font-weight: 600;
+        }
+        .bulk-actions-section {
+            background: #fff;
+            border: 2px dashed #d1d5db;
+            border-radius: 8px;
+            padding: 1.5rem;
+            transition: all 0.3s ease;
+        }
+        .bulk-actions-section:hover {
+            border-color: var(--nutri-green);
+            background: #f0fdf4;
+        }
+        .admin-recipe-card {
+            position: relative;
+            border: 2px solid #e5e7eb;
+            transition: all 0.3s ease;
+        }
+        .admin-recipe-card:hover {
+            border-color: var(--nutri-green);
+            transform: translateY(-2px);
+        }
+        .admin-recipe-card.selected {
+            border-color: #3b82f6;
+            background: #eff6ff;
+        }
+        .recipe-select {
+            position: absolute;
+            top: 10px;
+            left: 10px;
+            z-index: 10;
+        }
+        .recipe-checkbox {
+            width: 20px;
+            height: 20px;
+            cursor: pointer;
+            accent-color: #3b82f6;
+        }
+        .recipe-status-badge {
+            position: absolute;
+            top: 10px;
+            right: 10px;
+            z-index: 10;
+        }
+        .recipe-status-badge .badge {
+            font-size: 0.75rem;
+            padding: 0.25rem 0.5rem;
+        }
+        .admin-actions-buttons {
+            border-top: 1px solid #e5e7eb;
+            padding-top: 1rem;
+        }
+        .admin-actions-buttons .btn {
+            font-size: 0.875rem;
+            padding: 0.375rem 0.75rem;
+            font-weight: 500;
+        }
+        .decline-reason-section {
+            background: #fef2f2;
+            border: 1px solid #fecaca;
+            border-radius: 6px;
+            padding: 1rem;
+            animation: slideDown 0.3s ease;
+        }
+        @@keyframes slideDown {
+            from {
+                opacity: 0;
+                transform: translateY(-10px);
+            }
+            to {
+                opacity: 1;
+                transform: translateY(0);
+            }
+        }
+        .empty-state {
+            background: #f9fafb;
+            border: 2px dashed #d1d5db;
+            border-radius: 12px;
+            margin: 2rem 0;
+        }
+        .loading-overlay {
+            position: fixed;
+            top: 0;
+            left: 0;
+            width: 100%;
+            height: 100%;
+            background: rgba(0, 0, 0, 0.7);
+            display: flex;
+            flex-direction: column;
+            justify-content: center;
+            align-items: center;
+            z-index: 9999;
+            color: white;
+        }
+        .loading-overlay .spinner-border {
+            width: 3rem;
+            height: 3rem;
+        }
+        .recipe-image {
+            cursor: pointer;
+            transition: opacity 0.3s ease;
+        }
+        .recipe-image:hover {
+            opacity: 0.9;
+        }
+        .recipe-title {
+            cursor: pointer;
+            transition: color 0.3s ease;
+        }
+        .recipe-title:hover {
+            color: var(--nutri-green);
+        }
+        .btn:disabled {
+            opacity: 0.6;
+            cursor: not-allowed;
+        }
+        .btn-success:hover:not(:disabled) {
+            transform: translateY(-1px);
+            box-shadow: 0 4px 8px rgba(34, 197, 94, 0.3);
+        }
+        .btn-danger:hover:not(:disabled) {
+            transform: translateY(-1px);
+            box-shadow: 0 4px 8px rgba(239, 68, 68, 0.3);
+        }
+        @@media (max-width: 768px) {
+            .admin-header {
+                text-align: center;
+                padding: 1.5rem;
+            }
+            .admin-title {
+                font-size: 1.5rem;
+            }
+            .bulk-actions-section {
+                padding: 1rem;
+            }
+            .admin-actions-buttons {
+                display: flex;
+                flex-direction: column;
+                gap: 0.5rem;
+            }
+            .admin-actions-buttons .btn {
+                width: 100%;
+            }
+        }
+        .recipe-card.removing {
+            animation: fadeOut 0.5s ease forwards;
+        }
+        @@keyframes fadeOut {
+            from {
+                opacity: 1;
+                transform: scale(1);
+            }
+            to {
+                opacity: 0;
+                transform: scale(0.9);
+            }
+        }
+        .recipe-card.approved {
+            border-color: #10b981;
+            background: #f0fdf4;
+        }
+        .recipe-card.declined {
+            border-color: #ef4444;
+            background: #fef2f2;
+        }
+        .form-select-sm, .form-control-sm {
+            font-size: 0.875rem;
+        }
+        .decline-reason-section .form-label {
+            color: #991b1b;
+            margin-bottom: 0.5rem;
+        }
+        .search-container {
+            background: white;
+            border-radius: 8px;
+            padding: 1.5rem;
+            border: 1px solid #e5e7eb;
+            margin-bottom: 2rem;
+            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+        }
+        .admin-recipe-card .recipe-meta {
+            margin-bottom: 1rem;
+        }
+        .admin-recipe-card .recipe-meta span {
+            font-size: 0.875rem;
+            color: #6b7280;
+            margin-right: 1rem;
+        }
+    </style>
+</head>
+<body>
+    @Html.AntiForgeryToken()
+    <div class="container mt-4">
+        <div class="admin-header mb-4">
+            <div class="row align-items-center">
+                <div class="col-md-8">
+                    <h2 class="admin-title">
+                        <i class="fas fa-shield-alt me-2" style="color: var(--nutri-green);"></i>
+                        Recipe Approval Panel
+                    </h2>
+                    <p class="admin-subtitle text-muted">Review and manage pending recipe submissions</p>
+                </div>
+                <div class="col-md-4 text-end">
+                    <div class="admin-stats">
+                        <span class="badge bg-warning fs-6 me-2">
+                            <i class="fas fa-clock me-1"></i>
+                            @Model.Count Pending
+                        </span>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="search-container">
+            <div class="row align-items-center">
+                <div class="col-md-8">
+                    <input type="text" class="form-control search-input" placeholder="Search pending recipes..." id="searchInput">
+                </div>
+                <div class="col-md-4">
+                    <select class="form-select" id="sortFilter">
+                        <option value="newest">Newest First</option>
+                        <option value="oldest">Oldest First</option>
+                        <option value="author">By Author</option>
+                        <option value="calories">By Calories</option>
+                    </select>
+                </div>
+            </div>
+        </div>
+        <div class="bulk-actions-section mb-4">
+            <div class="row align-items-center">
+                <div class="col-md-6">
+                    <div class="form-check">
+                        <input class="form-check-input" type="checkbox" id="selectAll">
+                        <label class="form-check-label fw-bold" for="selectAll">
+                            Select All Recipes
+                        </label>
+                    </div>
+                </div>
+                <div class="col-md-6 text-end">
+                    <button class="btn btn-success me-2" id="bulkApprove" disabled>
+                        <i class="fas fa-check me-1"></i>Bulk Approve
+                    </button>
+                    <button class="btn btn-danger" id="bulkDecline" disabled>
+                        <i class="fas fa-times me-1"></i>Bulk Decline
+                    </button>
+                </div>
+            </div>
+        </div>
+        <div class="d-flex justify-content-between align-items-center mb-4">
+            <div class="results-count">
+                <i class="fas fa-utensils me-2"></i>
+                Showing <strong id="displayCount">@Model.Count</strong> pending recipes
+            </div>
+            <div class="admin-actions">
+                <button class="btn btn-outline-primary" onclick="refreshPendingRecipes()">
+                    <i class="fas fa-sync-alt me-1"></i>Refresh
+                </button>
+            </div>
+        </div>
+        <div class="recipe-grid" id="recipeGrid">
+            @foreach(var recipe in Model)
+            {
+                <div class="recipe-card admin-recipe-card" data-recipe-id="@recipe.Id" data-calories="@recipe.Calories" data-protein="@recipe.Protein" data-carbs="@recipe.Carbs" data-fat="@recipe.Fat">
+                    <div class="recipe-select">
+                        <input type="checkbox" class="recipe-checkbox" data-recipe-id="@recipe.Id">
+                    </div>
+                    <div class="recipe-status-badge">
+                        <span class="badge bg-warning">
+                            <i class="fas fa-clock me-1"></i>Pending
+                        </span>
+                    </div>
+                    <img src="@recipe.ImageUrl" alt="@recipe.Title" class="recipe-image" onclick="showRecipeDetails(@recipe.Id, true)">
+                    <div class="recipe-content">
+                        <h3 class="recipe-title" onclick="showRecipeDetails(@recipe.Id, true)">@recipe.Title</h3>
+                        <div class="recipe-meta">
+                            <span><i class="fas fa-user"></i>@recipe.User.UserName</span>
+                            <span><i class="fas fa-calendar"></i>@recipe.CreatedAt.ToString("MMM dd, yyyy")</span>
+                        </div>
+                        <div class="recipe-macros">
+                            <div class="macro-item">
+                                <div class="macro-value">@recipe.Calories</div>
+                                <div class="macro-label">Cal</div>
+                            </div>
+                            <div class="macro-item">
+                                <div class="macro-value">@recipe.Protein</div>
+                                <div class="macro-label">Protein</div>
+                            </div>
+                            <div class="macro-item">
+                                <div class="macro-value">@recipe.Carbs</div>
+                                <div class="macro-label">Carbs</div>
+                            </div>
+                            <div class="macro-item">
+                                <div class="macro-value">@recipe.Fat</div>
+                                <div class="macro-label">Fats</div>
+                            </div>
+                        </div>
+                        <div class="admin-actions-buttons mt-3">
+                            <button class="btn btn-success btn-sm me-2" onclick="approveRecipe(@recipe.Id, this)">
+                                <i class="fas fa-check me-1"></i>Approve
+                            </button>
+                            <button class="btn btn-danger btn-sm me-2" onclick="declineRecipe(@recipe.Id, this)">
+                                <i class="fas fa-times me-1"></i>Decline
+                            </button>
+                            <button class="btn btn-outline-primary btn-sm" onclick="showRecipeDetails(@recipe.Id, true)">
+                                <i class="fas fa-eye me-1"></i>Review
+                            </button>
+                        </div>
+                        <div class="decline-reason-section mt-3" style="display: none;" id="declineReason_@recipe.Id">
+                            <label class="form-label small fw-bold">Reason for decline:</label>
+                            <select class="form-select form-select-sm mb-2" id="declineSelect_@recipe.Id">
+                                <option value="">Select a reason...</option>
+                                <option value="inappropriate_content">Inappropriate Content</option>
+                                <option value="incomplete_recipe">Incomplete Recipe</option>
+                                <option value="poor_quality_image">Poor Quality Image</option>
+                                <option value="incorrect_nutrition">Incorrect Nutrition Info</option>
+                                <option value="duplicate_recipe">Duplicate Recipe</option>
+                                <option value="other">Other</option>
+                            </select>
+                            <textarea class="form-control form-control-sm mb-2" placeholder="Additional notes (optional)" id="declineNotes_@recipe.Id" rows="2"></textarea>
+                            <div class="text-end">
+                                <button class="btn btn-outline-secondary btn-sm me-1" onclick="cancelDecline(@recipe.Id)">Cancel</button>
+                                <button class="btn btn-danger btn-sm" onclick="confirmDecline(@recipe.Id)">
+                                    <i class="fas fa-times me-1"></i>Confirm Decline
+                                </button>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            }
+        </div>
+        @if(!Model.Any())
+        {
+            <div class="empty-state text-center py-5">
+                <i class="fas fa-check-circle text-success" style="font-size: 4rem;"></i>
+                <h3 class="mt-3">All Caught Up!</h3>
+                <p class="text-muted">There are no pending recipes to review at this time.</p>
+                <button class="btn btn-primary" onclick="window.location.reload()">
+                    <i class="fas fa-sync-alt me-1"></i>Check Again
+                </button>
+            </div>
+        }
+    </div>
+    <div id="modalWindow"></div>
+    <div id="loadingOverlay" class="loading-overlay" style="display: none;">
+        <div class="spinner-border text-primary" role="status">
+            <span class="visually-hidden">Processing...</span>
+        </div>
+        <p class="mt-3">Processing request...</p>
+    </div>
+    <script src="~/js/RecipeIndex.js"></script>
+    <script>
+    document.addEventListener('DOMContentLoaded', function() {
+        initializeAdminPanel();
+    });
+    function initializeAdminPanel() {
+        setupBulkActions();
+        setupSearchFunctionality();
+        setupSortingFunctionality();
+        updateDisplayCount();
+    }
+    function setupBulkActions() {
+        const selectAllCheckbox = document.getElementById('selectAll');
+        const recipeCheckboxes = document.querySelectorAll('.recipe-checkbox');
+        const bulkApproveBtn = document.getElementById('bulkApprove');
+        const bulkDeclineBtn = document.getElementById('bulkDecline');
+        selectAllCheckbox.addEventListener('change', function() {
+            recipeCheckboxes.forEach(checkbox => {
+                checkbox.checked = this.checked;
+                toggleRecipeSelection(checkbox);
+            });
+            updateBulkActionButtons();
+        });
+        recipeCheckboxes.forEach(checkbox => {
+            checkbox.addEventListener('change', function() {
+                toggleRecipeSelection(this);
+                updateBulkActionButtons();
+                updateSelectAllState();
+            });
+        });
+        bulkApproveBtn.addEventListener('click', handleBulkApprove);
+        bulkDeclineBtn.addEventListener('click', handleBulkDecline);
+    }
+    function toggleRecipeSelection(checkbox) {
+        const recipeCard = checkbox.closest('.recipe-card');
+        if (checkbox.checked) {
+            recipeCard.classList.add('selected');
+        } else {
+            recipeCard.classList.remove('selected');
+        }
+    }
+    function updateBulkActionButtons() {
+        const selectedCheckboxes = document.querySelectorAll('.recipe-checkbox:checked');
+        const bulkApproveBtn = document.getElementById('bulkApprove');
+        const bulkDeclineBtn = document.getElementById('bulkDecline');
+        const hasSelections = selectedCheckboxes.length > 0;
+        bulkApproveBtn.disabled = !hasSelections;
+        bulkDeclineBtn.disabled = !hasSelections;
+    }
+    function updateSelectAllState() {
+        const selectAllCheckbox = document.getElementById('selectAll');
+        const recipeCheckboxes = document.querySelectorAll('.recipe-checkbox');
+        const checkedBoxes = document.querySelectorAll('.recipe-checkbox:checked');
+        if (checkedBoxes.length === 0) {
+            selectAllCheckbox.indeterminate = false;
+            selectAllCheckbox.checked = false;
+        } else if (checkedBoxes.length === recipeCheckboxes.length) {
+            selectAllCheckbox.indeterminate = false;
+            selectAllCheckbox.checked = true;
+        } else {
+            selectAllCheckbox.indeterminate = true;
+        }
+    }
+    function approveRecipe(recipeId, button) {
+        if (!confirm('Are you sure you want to approve this recipe?')) {
+            return;
+        }
+        showLoadingOverlay();
+        const token = document.querySelector('input[name="__RequestVerificationToken"]').value;
+        fetch('/Admin/ApproveRecipe', {
+            method: 'POST',
+            headers: {
+                'Content-Type': 'application/json',
+                'RequestVerificationToken': token
+            },
+            body: JSON.stringify({ recipeId: recipeId })
+        })
+        .then(response => response.json())
+        .then(data => {
+            hideLoadingOverlay();
+            if (data.success) {
+                showSuccess('Recipe approved successfully!');
+                removeRecipeCard(recipeId);
+            } else {
+                showError(data.message || 'Failed to approve recipe');
+            }
+        })
+        .catch(error => {
+            hideLoadingOverlay();
+            console.error('Error:', error);
+            showError('An error occurred while approving the recipe');
+        });
+    }
+    function declineRecipe(recipeId, button) {
+        const declineSection = document.getElementById(`declineReason_${recipeId}`);
+        const recipeCard = button.closest('.recipe-card');
+        declineSection.style.display = 'block';
+        button.style.display = 'none';
+        const actionButtons = recipeCard.querySelectorAll('.admin-actions-buttons .btn:not(.btn-outline-secondary)');
+        actionButtons.forEach(btn => {
+            if (btn !== button && !btn.classList.contains('btn-outline-secondary')) {
+                btn.style.display = 'none';
+            }
+        });
+    }
+    function cancelDecline(recipeId) {
+        const declineSection = document.getElementById(`declineReason_${recipeId}`);
+        const recipeCard = declineSection.closest('.recipe-card');
+        declineSection.style.display = 'none';
+        const actionButtons = recipeCard.querySelectorAll('.admin-actions-buttons .btn');
+        actionButtons.forEach(btn => {
+            btn.style.display = '';
+        });
+        document.getElementById(`declineSelect_${recipeId}`).value = '';
+        document.getElementById(`declineNotes_${recipeId}`).value = '';
+    }
+    function confirmDecline(recipeId) {
+        const reason = document.getElementById(`declineSelect_${recipeId}`).value;
+        const notes = document.getElementById(`declineNotes_${recipeId}`).value;
+        if (!reason) {
+            showError('Please select a reason for declining the recipe');
+            return;
+        }
+        showLoadingOverlay();
+        const token = document.querySelector('input[name="__RequestVerificationToken"]').value;
+        fetch('/Admin/DeclineRecipe', {
+            method: 'POST',
+            headers: {
+                'Content-Type': 'application/json',
+                'RequestVerificationToken': token
+            },
+            body: JSON.stringify({
+                recipeId: recipeId,
+            })
+        })
+        .then(response => response.json())
+        .then(data => {
+            hideLoadingOverlay();
+            if (data.success) {
+                showSuccess('Recipe declined successfully!');
+                removeRecipeCard(recipeId);
+            } else {
+                showError(data.message || 'Failed to decline recipe');
+            }
+        })
+        .catch(error => {
+            hideLoadingOverlay();
+            console.error('Error:', error);
+            showError('An error occurred while declining the recipe');
+        });
+    }
+    function handleBulkApprove() {
+        const selectedRecipes = getSelectedRecipeIds();
+        if (selectedRecipes.length === 0) {
+            showError('No recipes selected');
+            return;
+        }
+        if (!confirm(`Are you sure you want to approve ${selectedRecipes.length} recipe(s)?`)) {
+            return;
+        }
+        showLoadingOverlay();
+        const token = document.querySelector('input[name="__RequestVerificationToken"]').value;
+        fetch('/Admin/BulkApproveRecipes', {
+            method: 'POST',
+            headers: {
+                'Content-Type': 'application/json',
+                'RequestVerificationToken': token
+            },
+            body: JSON.stringify({ recipeIds: selectedRecipes })
+        })
+        .then(response => response.json())
+        .then(data => {
+            hideLoadingOverlay();
+            if (data.success) {
+                showSuccess(`${data.approvedCount} recipe(s) approved successfully!`);
+                selectedRecipes.forEach(recipeId => removeRecipeCard(recipeId));
+            } else {
+                showError(data.message || 'Failed to approve recipes');
+            }
+        })
+        .catch(error => {
+            hideLoadingOverlay();
+            console.error('Error:', error);
+            showError('An error occurred during bulk approval');
+        });
+    }
+    function handleBulkDecline() {
+        const selectedRecipes = getSelectedRecipeIds();
+        if (selectedRecipes.length === 0) {
+            showError('No recipes selected');
+            return;
+        }
+        showBulkDeclineModal(selectedRecipes);
+    }
+    function getSelectedRecipeIds() {
+        const selectedCheckboxes = document.querySelectorAll('.recipe-checkbox:checked');
+        return Array.from(selectedCheckboxes).map(checkbox => parseInt(checkbox.dataset.recipeId));
+    }
+    function setupSearchFunctionality() {
+        const searchInput = document.getElementById('searchInput');
+        let searchTimeout;
+        searchInput.addEventListener('input', function() {
+            clearTimeout(searchTimeout);
+            searchTimeout = setTimeout(() => {
+                filterRecipes();
+            }, 300);
+        });
+    }
+    function filterRecipes() {
+        const searchTerm = document.getElementById('searchInput').value.toLowerCase();
+        const recipeCards = document.querySelectorAll('.recipe-card');
+        let visibleCount = 0;
+        recipeCards.forEach(card => {
+            const title = card.querySelector('.recipe-title').textContent.toLowerCase();
+            const author = card.querySelector('.recipe-meta span').textContent.toLowerCase();
+            const isVisible = title.includes(searchTerm) || author.includes(searchTerm);
+            card.style.display = isVisible ? 'block' : 'none';
+            if (isVisible) visibleCount++;
+        });
+        updateDisplayCount(visibleCount);
+    }
+    function setupSortingFunctionality() {
+        const sortFilter = document.getElementById('sortFilter');
+        sortFilter.addEventListener('change', function() {
+            sortRecipes(this.value);
+        });
+    }
+    function sortRecipes(sortBy) {
+        const recipeGrid = document.getElementById('recipeGrid');
+        const recipeCards = Array.from(recipeGrid.querySelectorAll('.recipe-card'));
+        recipeCards.sort((a, b) => {
+            switch (sortBy) {
+                case 'newest':
+                    return parseInt(b.dataset.recipeId) - parseInt(a.dataset.recipeId);
+                case 'oldest':
+                    return parseInt(a.dataset.recipeId) - parseInt(b.dataset.recipeId);
+                case 'author':
+                    const authorA = a.querySelector('.recipe-meta span').textContent.toLowerCase();
+                    const authorB = b.querySelector('.recipe-meta span').textContent.toLowerCase();
+                    return authorA.localeCompare(authorB);
+                case 'calories':
+                    return parseInt(a.dataset.calories) - parseInt(b.dataset.calories);
+                default:
+                    return 0;
+            }
+        });
+        recipeCards.forEach(card => recipeGrid.appendChild(card));
+    }
+    function removeRecipeCard(recipeId) {
+        const recipeCard = document.querySelector(`[data-recipe-id="${recipeId}"]`);
+        if (recipeCard) {
+            recipeCard.classList.add('removing');
+            setTimeout(() => {
+                recipeCard.remove();
+                updateDisplayCount();
+                updateBulkActionButtons();
+                updateSelectAllState();
+                if (document.querySelectorAll('.recipe-card').length === 0) {
+                    location.reload();
+                }
+            }, 500);
+        }
+    }
+    function updateDisplayCount(count = null) {
+        const displayCountElement = document.getElementById('displayCount');
+        if (count === null) {
+            count = document.querySelectorAll('.recipe-card:not([style*="display: none"])').length;
+        }
+        displayCountElement.textContent = count;
+    }
+    function showLoadingOverlay() {
+        document.getElementById('loadingOverlay').style.display = 'flex';
+    }
+    function hideLoadingOverlay() {
+        document.getElementById('loadingOverlay').style.display = 'none';
+    }
+    function showSuccess(message) {
+        alert(message);
+    }
+    function showError(message) {
+        alert(message);
+    }
+    function refreshPendingRecipes() {
+        location.reload();
+    }
+    function showRecipeDetails(recipeId, isAdmin = false) {
+            fetch(`/Recipes/Details/${recipeId}`)
+        .then(response => {
+            if (!response.ok) {
+                throw new Error('Network response was not ok');
+            }
+            return response.text();
+        })
+        .then(html => {
+            const modalContainer = document.getElementById('modalWindow');
+            modalContainer.innerHTML = html;
+            const scripts = modalContainer.querySelectorAll("script");
+            scripts.forEach(script => {
+                const newScript = document.createElement("script");
+                if (script.src) {
+                    newScript.src = script.src;
+                } else {
+                    newScript.textContent = script.textContent;
+                }
+                document.body.appendChild(newScript);
+                document.body.removeChild(newScript);
+            });
+            const modalElement = modalContainer.querySelector('.modal');
+            if (modalElement) {
+                const modal = new bootstrap.Modal(modalElement);
+                modal.show();
+                modalElement.addEventListener('hidden.bs.modal', function () {
+                    modalContainer.innerHTML = '';
+                    clickedCard.classList.remove('loading');
+                }); 
+                modalElement.addEventListener('shown.bs.modal', function () {
+                    clickedCard.classList.remove('loading');
+                });
+            } else {    
+                clickedCard.classList.remove('loading');
+            }
+        })
+        .catch(err => {
+            console.error("Failed to fetch recipe details", err);
+            alert("Failed to load recipe details. Please try again.");
+            clickedCard.classList.remove('loading');
+        });
+            addAdminControlsToModal(recipeId);
+    }
+    function addAdminControlsToModal(recipeId) {
+        const modalFooter = document.querySelector('#modalWindow .modal-footer');
+        if (modalFooter) {
+            const adminControls = `
+                <div class="admin-modal-controls me-auto">
+                    <button class="btn btn-success me-2" onclick="approveRecipe(${recipeId}, this); closeModal();">
+                        <i class="fas fa-check me-1"></i>Approve Recipe
+                    </button>
+                    <button class="btn btn-danger" onclick="declineRecipeFromModal(${recipeId})">
+                        <i class="fas fa-times me-1"></i>Decline Recipe
+                    </button>
+                </div>
+            `;
+            modalFooter.insertAdjacentHTML('afterbegin', adminControls);
+        }
+    }
+    function declineRecipeFromModal(recipeId) {
+        const modalBody = document.querySelector('#modalWindow .modal-body');
+        const declineForm = `
+            <div class="decline-reason-modal mt-4 p-3" style="background: #fef2f2; border: 1px solid #fecaca; border-radius: 8px;">
+                <h6 class="text-danger mb-3">
+                    <i class="fas fa-exclamation-triangle me-2"></i>
+                    Decline Recipe
+                </h6>
+                <div class="mb-3">
+                    <label class="form-label">Reason for decline:</label>
+                    <select class="form-select" id="modalDeclineSelect">
+                        <option value="">Select a reason...</option>
+                        <option value="inappropriate_content">Inappropriate Content</option>
+                        <option value="incomplete_recipe">Incomplete Recipe</option>
+                        <option value="poor_quality_image">Poor Quality Image</option>
+                        <option value="incorrect_nutrition">Incorrect Nutrition Info</option>
+                        <option value="duplicate_recipe">Duplicate Recipe</option>
+                        <option value="other">Other</option>
+                    </select>
+                </div>
+                <div class="mb-3">
+                    <label class="form-label">Additional notes (optional):</label>
+                    <textarea class="form-control" id="modalDeclineNotes" rows="3" placeholder="Provide additional details about why this recipe is being declined..."></textarea>
+                </div>
+                <div class="text-end">
+                    <button class="btn btn-outline-secondary me-2" onclick="cancelModalDecline()">Cancel</button>
+                    <button class="btn btn-danger" onclick="confirmModalDecline(${recipeId})">
+                        <i class="fas fa-times me-1"></i>Confirm Decline
+                    </button>
+                </div>
+            </div>
+        `;
+        modalBody.insertAdjacentHTML('beforeend', declineForm);
+        const adminControls = document.querySelector('.admin-modal-controls');
+        if (adminControls) {
+            adminControls.style.display = 'none';
+        }
+    }
+    function cancelModalDecline() {
+        const declineForm = document.querySelector('.decline-reason-modal');
+        const adminControls = document.querySelector('.admin-modal-controls');
+        if (declineForm) {
+            declineForm.remove();
+        }
+        if (adminControls) {
+            adminControls.style.display = 'block';
+        }
+    }
+    function confirmModalDecline(recipeId) {
+        const reason = document.getElementById('modalDeclineSelect').value;
+        const notes = document.getElementById('modalDeclineNotes').value;
+        if (!reason) {
+            showError('Please select a reason for declining the recipe');
+            return;
+        }
+        showLoadingOverlay();
+        const token = document.querySelector('input[name="__RequestVerificationToken"]').value;
+        fetch('/Admin/DeclineRecipe', {
+            method: 'POST',
+            headers: {
+                'Content-Type': 'application/json',
+                'RequestVerificationToken': token
+            },
+            body: JSON.stringify({
+                recipeId: recipeId,
+            })
+        })
+        .then(response => response.json())
+        .then(data => {
+            hideLoadingOverlay();
+            if (data.success) {
+                showSuccess('Recipe declined successfully!');
+                closeModal();
+                removeRecipeCard(recipeId);
+            } else {
+                showError(data.message || 'Failed to decline recipe');
+            }
+        })
+        .catch(error => {
+            hideLoadingOverlay();
+            console.error('Error:', error);
+            showError('An error occurred while declining the recipe');
+        });
+    }
+    function closeModal() {
+        const modal = document.getElementById('modalWindow');
+        modal.innerHTML = '';
+    }
+    function showBulkDeclineModal(recipeIds) {
+        const modalHtml = `
+            <div class="modal fade show" style="display: block;" tabindex="-1">
+                <div class="modal-dialog modal-lg">
+                    <div class="modal-content">
+                        <div class="modal-header">
+                            <h5 class="modal-title text-danger">
+                                <i class="fas fa-exclamation-triangle me-2"></i>
+                                Bulk Decline Recipes
+                            </h5>
+                            <button type="button" class="btn-close" onclick="closeBulkDeclineModal()"></button>
+                        </div>
+                        <div class="modal-body">
+                            <div class="alert alert-warning">
+                                <i class="fas fa-info-circle me-2"></i>
+                                You are about to decline <strong>${recipeIds.length}</strong> recipe(s). This action cannot be undone.
+                            </div>
+                            <div class="mb-3">
+                                <label class="form-label fw-bold">Reason for decline:</label>
+                                <select class="form-select" id="bulkDeclineSelect" required>
+                                    <option value="">Select a reason...</option>
+                                    <option value="inappropriate_content">Inappropriate Content</option>
+                                    <option value="incomplete_recipe">Incomplete Recipe</option>
+                                    <option value="poor_quality_image">Poor Quality Image</option>
+                                    <option value="incorrect_nutrition">Incorrect Nutrition Info</option>
+                                    <option value="duplicate_recipe">Duplicate Recipe</option>
+                                    <option value="other">Other</option>
+                                </select>
+                            </div>
+                            <div class="mb-3">
+                                <label class="form-label fw-bold">Additional notes (optional):</label>
+                                <textarea class="form-control" id="bulkDeclineNotes" rows="4" placeholder="Provide additional details about why these recipes are being declined..."></textarea>
+                            </div>
+                        </div>
+                        <div class="modal-footer">
+                            <button type="button" class="btn btn-outline-secondary" onclick="closeBulkDeclineModal()">Cancel</button>
+                            <button type="button" class="btn btn-danger" onclick="confirmBulkDecline([${recipeIds.join(',')}])">
+                                <i class="fas fa-times me-1"></i>Decline ${recipeIds.length} Recipe(s)
+                            </button>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="modal-backdrop fade show"></div>
+        `;
+        document.getElementById('modalWindow').innerHTML = modalHtml;
+    }
+    function closeBulkDeclineModal() {
+        document.getElementById('modalWindow').innerHTML = '';
+    }
+    function confirmBulkDecline(recipeIds) {
+        const reason = document.getElementById('bulkDeclineSelect').value;
+        const notes = document.getElementById('bulkDeclineNotes').value;
+        if (!reason) {
+            showError('Please select a reason for declining the recipes');
+            return;
+        }
+        showLoadingOverlay();
+        closeBulkDeclineModal();
+        const token = document.querySelector('input[name="__RequestVerificationToken"]').value;
+        fetch('/Admin/BulkDeclineRecipes', {
+            method: 'POST',
+            headers: {
+                'Content-Type': 'application/json',
+                'RequestVerificationToken': token
+            },
+            body: JSON.stringify({
+                recipeIds: recipeIds
+            })
+        })
+        .then(response => response.json())
+        .then(data => {
+            hideLoadingOverlay();
+            if (data.success) {
+                showSuccess(`${data.declinedCount} recipe(s) declined successfully!`);
+                recipeIds.forEach(recipeId => removeRecipeCard(recipeId));
+            } else {
+                showError(data.message || 'Failed to decline recipes');
+            }
+        })
+        .catch(error => {
+            hideLoadingOverlay();
+            console.error('Error:', error);
+            showError('An error occurred during bulk decline');
+        });
+    }
+    function createToast(message, type = 'info') {
+        const toastContainer = document.getElementById('toast-container') || createToastContainer();
+        const toast = document.createElement('div');
+        toast.className = `toast align-items-center text-white bg-${type} border-0`;
+        toast.setAttribute('role', 'alert');
+        toast.setAttribute('aria-live', 'assertive');
+        toast.setAttribute('aria-atomic', 'true');
+        toast.innerHTML = `
+            <div class="d-flex">
+                <div class="toast-body">
+                    ${message}
+                </div>
+                <button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
+            </div>
+        `;
+        toastContainer.appendChild(toast);
+        setTimeout(() => {
+            if (toast.parentNode) {
+                toast.remove();
+            }
+        }, 5000);
+    }
+    function createToastContainer() {
+        const container = document.createElement('div');
+        container.id = 'toast-container';
+        container.className = 'toast-container position-fixed top-0 end-0 p-3';
+        container.style.zIndex = '1055';
+        document.body.appendChild(container);
+        return container;
+    }
+    function showSuccess(message) {
+        createToast(message, 'success');
+    }
+    function showError(message) {
+        createToast(message, 'danger');
+    }
+    document.addEventListener('keydown', function(e) {
+        if ((e.ctrlKey || e.metaKey) && e.key === 'a' && e.target.tagName !== 'INPUT' && e.target.tagName !== 'TEXTAREA') {
+            e.preventDefault();
+            const selectAllCheckbox = document.getElementById('selectAll');
+            selectAllCheckbox.checked = !selectAllCheckbox.checked;
+            selectAllCheckbox.dispatchEvent(new Event('change'));
+        }
+        if (e.key === 'Escape') {
+            closeModal();
+            closeBulkDeclineModal();
+        }
+    });
+    </script>
+</body>
+</html>
Index: NutriMatch/Views/Home/Index.cshtml
===================================================================
--- NutriMatch/Views/Home/Index.cshtml	(revision a8860663d8380fb13055bfa6006477787df4824f)
+++ NutriMatch/Views/Home/Index.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -9,54 +9,56 @@
 </head>
 <body>
-    <section class="signup-section" style="margin-top: 200px;">
-        <div class="floating-elements">
-            <i class="fas fa-leaf floating-leaf" style="top: 10%; left: 15%; font-size: 2rem;"></i>
-            <i class="fas fa-seedling floating-leaf" style="top: 60%; right: 20%; font-size: 1.5rem; animation-delay: -2s;"></i>
-            <i class="fas fa-leaf floating-leaf" style="top: 30%; right: 10%; font-size: 2.5rem; animation-delay: -4s;"></i>
-        </div>
-        <div class="container">
-            <div class="row align-items-center">
-                <div class="daily-dish col-lg-6">
-                    <h1 class="signup-title">Create your account</h1>
-                    <h2 class="signup-subtitle">Optimize Your Nutrition</h2>
-                    <p class="signup-description">
-                        Join our macro-focused recipe platform designed for goal-oriented eating. <br/>
-                        As a member, you can
-                        create and manage your own recipes,
-                        rate and review meals from the community,
-                        save your favorite dishes for quick access and
-                        filter recipes by macronutrient profiles that align with your dietary needs
-                    </p>
-                    <button class="btn btn-primary-custom">
-                        Sign up
-                    </button>
-                    <p class="mt-3 text-muted">Already have an account? <a href="#" style="color: var(--primary-green); text-decoration: none;">Log in</a></p>
-                </div>
-                <div class="col-lg-4 text-center">
-                    <div class="position-relative">
-                        <img src="https://images.unsplash.com/photo-1546069901-ba9599a7e63c?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80" 
-                             alt="Delicious Food Bowl" class="img-fluid rounded-circle" style="width: 300px; height: 300px; object-fit: cover; box-shadow: 0 20px 40px rgba(0,0,0,0.2);">
-                        <div class="position-absolute" style="top: 20px; right: 20px; background: white; border-radius: 50px; padding: 8px 15px; box-shadow: 0 5px 15px rgba(0,0,0,0.1);">
-                            <div class="d-flex align-items-center gap-2">
-                                <img src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-4.0.3&auto=format&fit=crop&w=50&q=80" 
-                                     alt="Chef" class="rounded-circle" style="width: 30px; height: 30px; object-fit: cover;">
-                                <div>
-                                    <small class="fw-bold text-dark d-block">Chef Milan</small>
-                                    <div class="text-warning" style="font-size: 12px;">
-                                        <i class="fas fa-star"></i>
-                                        <i class="fas fa-star"></i>
-                                        <i class="fas fa-star"></i>
-                                        <i class="fas fa-star"></i>
-                                        <i class="fas fa-star"></i>
+    @if (!User.Identity.IsAuthenticated){
+        <section class="signup-section" style="margin-top: 200px;">
+            <div class="floating-elements">
+                <i class="fas fa-leaf floating-leaf" style="top: 10%; left: 15%; font-size: 2rem;"></i>
+                <i class="fas fa-seedling floating-leaf" style="top: 60%; right: 20%; font-size: 1.5rem; animation-delay: -2s;"></i>
+                <i class="fas fa-leaf floating-leaf" style="top: 30%; right: 10%; font-size: 2.5rem; animation-delay: -4s;"></i>
+            </div>
+            <div class="container">
+                <div class="row align-items-center">
+                    <div class="daily-dish col-lg-6">
+                        <h1 class="signup-title">Create your account</h1>
+                        <h2 class="signup-subtitle">Optimize Your Nutrition</h2>
+                        <p class="signup-description">
+                            Join our macro-focused recipe platform designed for goal-oriented eating. <br/>
+                            As a member, you can
+                            create and manage your own recipes,
+                            rate and review meals from the community,
+                            save your favorite dishes for quick access and
+                            filter recipes by macronutrient profiles that align with your dietary needs
+                        </p>
+                        <button class="btn btn-primary-custom">
+                            Sign up
+                        </button>
+                        <p class="mt-3 text-muted">Already have an account? <a href="#" style="color: var(--primary-green); text-decoration: none;">Log in</a></p>
+                    </div>
+                    <div class="col-lg-4 text-center">
+                        <div class="position-relative">
+                            <img src="https://images.unsplash.com/photo-1546069901-ba9599a7e63c?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80" 
+                                alt="Delicious Food Bowl" class="img-fluid rounded-circle" style="width: 300px; height: 300px; object-fit: cover; box-shadow: 0 20px 40px rgba(0,0,0,0.2);">
+                            <div class="position-absolute" style="top: 20px; right: 20px; background: white; border-radius: 50px; padding: 8px 15px; box-shadow: 0 5px 15px rgba(0,0,0,0.1);">
+                                <div class="d-flex align-items-center gap-2">
+                                    <img src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-4.0.3&auto=format&fit=crop&w=50&q=80" 
+                                        alt="Chef" class="rounded-circle" style="width: 30px; height: 30px; object-fit: cover;">
+                                    <div>
+                                        <small class="fw-bold text-dark d-block">Chef John</small>
+                                        <div class="text-warning" style="font-size: 12px;">
+                                            <i class="fas fa-star"></i>
+                                            <i class="fas fa-star"></i>
+                                            <i class="fas fa-star"></i>
+                                            <i class="fas fa-star"></i>
+                                            <i class="fas fa-star"></i>
+                                        </div>
                                     </div>
                                 </div>
+                                <small class="text-muted d-block mt-1">  </small>
                             </div>
-                            <small class="text-muted d-block mt-1">  </small>
                         </div>
                     </div>
                 </div>
             </div>
-        </div>
-    </section>
+        </section>
+    }
     <section class="share-recipe-section">
         <div class="container">
@@ -88,7 +90,7 @@
                         Have a recipe that fits your nutrition goals? Share it with the community and help others discover meals that balance flavor and function. Whether it’s high-protein, low-carb, or macro-balanced — your creations make a difference.
                     </p>
-                    <button class="btn btn-create-recipe">
+                    <a href="/Recipes/Create" class="btn btn-create-recipe">
                         Create New Recipe
-                    </button>
+                    </a>
                 </div>
             </div>
@@ -103,7 +105,4 @@
                     <div class="col-md-6 col-lg-4">
                         <div class="recipe-card">
-                            <button class="favorite-btn">
-                                <i class="far fa-heart"></i>
-                            </button>
                             <img src="@recipe.ImageUrl" class="recipe-image">
                             <div class="recipe-content">
@@ -111,7 +110,8 @@
                                 <div class="recipe-meta">
                                     <span class="rating">
-                                        <i class="fas fa-star"></i> 4.8
+                                        <i class="fas fa-star"></i> @recipe.Rating
                                     </span>
-                                    <span><i class="fas fa-user"></i> Chef Mario</span>
+                                    <span><i class="fas fa-user"></i> @recipe.User.UserName</span>
+                                    <span><i class="fas fa-calendar"> </i> @recipe.CreatedAt.ToString("MMM dd, yyyy")</span>
                                 </div>
                                 <div class="calories-info">
@@ -179,12 +179,4 @@
                         <div class="restaurant-name">@restaurant.Name</div>
                         <div class="restaurant-items">@restaurant.Description</div>
-                        <div class="restaurant-rating">
-                            <i class="fas fa-star"></i>
-                            <i class="fas fa-star"></i>
-                            <i class="fas fa-star"></i>
-                            <i class="fas fa-star-half-alt"></i>
-                            <i class="far fa-star"></i>
-                            4.2
-                        </div>
                     </div>
                 }
Index: NutriMatch/Views/Recipes/Create.cshtml
===================================================================
--- NutriMatch/Views/Recipes/Create.cshtml	(revision a8860663d8380fb13055bfa6006477787df4824f)
+++ NutriMatch/Views/Recipes/Create.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -85,5 +85,5 @@
                             <p><strong>Click to upload</strong> or drag and drop</p>
                             <p>PNG, JPG, GIF up to 10MB</p>
-                            <input  type="file" id="RecipeImage" name="RecipeImage" accept="image/*" style="display: none;">
+                            <input  type="file" id="RecipeImage" name="RecipeImage" accept="image/*" style="display: none;" required/>
                         </div>
                         <div id="imagePreview" style="margin-top: 1rem; text-align: center;"></div>
Index: NutriMatch/Views/Recipes/Index.cshtml
===================================================================
--- NutriMatch/Views/Recipes/Index.cshtml	(revision a8860663d8380fb13055bfa6006477787df4824f)
+++ NutriMatch/Views/Recipes/Index.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -12,14 +12,10 @@
 </head>
 <body>
+    @Html.AntiForgeryToken()
     <div class="container mt-4">
         <div class="search-container">
             <div class="row align-items-center">
-                <div class="col-md-10">
+                <div class="col-md-12">
                     <input type="text" class="form-control search-input" placeholder="Search recipes..." id="searchInput">
-                </div>
-                <div class="col-md-2">
-                    <button class="btn search-btn w-100" onclick="searchRecipes()">
-                        <i class="fas fa-search me-2"></i>Search
-                    </button>
                 </div>
             </div>
@@ -86,14 +82,23 @@
             </div>
         </div>
-        <div class="results-count">
+        <div class=" d-flex justify-content-between align-items-center mb-4">
+            <div class="results-count">
             <i class="fas fa-utensils me-2"></i>Showing <strong> recipes</strong> matching your criteria
+            </div>
+            <div class="col-md-4">
+                    <button class="btn btn-outline-success w-100" id="favoritesToggle" onclick="toggleFavoritesFilter()">
+                        <i class="fas fa-heart me-2"></i>Show Favorites Only
+                    </button>
+            </div>
         </div>
         <div class="recipe-grid" id="recipeGrid">
             @foreach(var recipe in Model)
             {
-                <div class="recipe-card" onclick="showRecipeDetails(@recipe.Id)" data-calories="@recipe.Calories" data-protein="@recipe.Protein" data-carbs="@recipe.Carbs" data-fat="@recipe.Fat">
-                    <button class="favorite-btn" onclick="event.stopPropagation(); toggleFavorite(this)">
-                        <i class="far fa-heart"></i>
-                    </button>
+                var isFavorited = ViewBag.FavoriteRecipeIds != null && ((List<int>)ViewBag.FavoriteRecipeIds).Contains(recipe.Id);
+                <div class="recipe-card" onclick="showRecipeDetails(@recipe.Id,false)" data-calories="@recipe.Calories" data-protein="@recipe.Protein" data-carbs="@recipe.Carbs" data-fat="@recipe.Fat">
+                @if(recipe.User.Id != ViewBag.userId){
+                    <button class="favorite-btn" onclick="event.stopPropagation(); toggleFavoriteFromIndex(this, @recipe.Id)" data-recipe-id="@recipe.Id" data-favorited="@isFavorited.ToString().ToLower()">
+                        <i class="@(isFavorited ? "fas" : "far") fa-heart"></i>
+                    </button>}
                     <img src="@recipe.ImageUrl" alt="@recipe.Title" class="recipe-image">
                     <div class="recipe-content">
@@ -101,7 +106,8 @@
                         <div class="recipe-meta">
                             <span class="rating">
-                                <i class="fas fa-star"></i> 4.8
+                                <i class="fas fa-star"></i> @recipe.Rating
                             </span>
-                            <span><i class="fas fa-user"></i> Chef Mario</span>
+                            <span><i class="fas fa-user"></i>@recipe.User.UserName</span>
+                            <span><i class="fas fa-calendar"> </i> @recipe.CreatedAt.ToString("MMM dd, yyyy")</span>
                         </div>
                         <div class="recipe-macros">
@@ -129,5 +135,4 @@
     </div>
     <div id="modalWindow"></div>
-    <div id="modalWindowDelete"></div>
     <script src="~/js/RecipeIndex.js"></script>
 </body>
Index: NutriMatch/Views/Recipes/MyRecipes.cshtml
===================================================================
--- NutriMatch/Views/Recipes/MyRecipes.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Views/Recipes/MyRecipes.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,459 @@
+@model List<Recipe>
+@{
+    ViewData["Title"] = "My Recipes";
+    Layout = "~/Views/Shared/_Layout.cshtml";
+}
+<style>
+    :root {
+    --primary-green: #2ECC71;
+    --dark-green: #27AE60;
+    --light-green: #58D68D;
+    --light-green-gray: #bbcabe;
+    --dark-gray: #2C3E50;
+    --light-gray: #ECF0F1;
+    --nutri-light-gray: #f3f4f6;
+    --nutri-green-dark: #22c55e;
+}
+    body {
+         font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+        background: linear-gradient(135deg, var(--light-pink) 0%, white 50%, var(--light-green-gray) 100%);
+        margin: 0;
+        padding: 0;
+        min-height: 100vh;
+    }
+    .container {
+        max-width: 1200px;
+        margin: 0 auto;
+        padding: 40px 20px;
+    }
+    .header-section {
+        background: rgba(255, 255, 255, 0.9);
+        border-radius: 20px;
+        padding: 40px;
+        margin-bottom: 30px;
+        box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
+        backdrop-filter: blur(10px);
+        text-align: center;
+    }
+    .header-section h1 {
+        color: #2c3e50;
+        font-size: 2.5rem;
+        font-weight: 600;
+        margin: 0 0 15px 0;
+    }
+    .header-section p {
+        color: #7f8c8d;
+        font-size: 1.1rem;
+        margin: 0 0 30px 0;
+        line-height: 1.6;
+    }
+    .create-recipe-btn {
+        background: #52c96b;
+        color: white;
+        padding: 15px 30px;
+        border: none;
+        border-radius: 25px;
+        font-size: 1.1rem;
+        font-weight: 600;
+        text-decoration: none;
+        display: inline-block;
+        transition: all 0.3s ease;
+        box-shadow: 0 5px 15px rgba(82, 201, 107, 0.3);
+    }
+    .create-recipe-btn:hover {
+        background: #47b35f;
+        transform: translateY(-2px);
+        box-shadow: 0 8px 25px rgba(82, 201, 107, 0.4);
+        color: white;
+        text-decoration: none;
+    }
+    .stats-section {
+        display: grid;
+        grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+        gap: 20px;
+        margin-bottom: 30px;
+    }
+    .stat-card {
+        background: rgba(255, 255, 255, 0.8);
+        border-radius: 15px;
+        padding: 25px;
+        text-align: center;
+        box-shadow: 0 5px 20px rgba(0, 0, 0, 0.08);
+        backdrop-filter: blur(5px);
+    }
+    .stat-number {
+        font-size: 2rem;
+        font-weight: 700;
+        color: #52c96b;
+        margin-bottom: 5px;
+    }
+    .stat-label {
+        color: #7f8c8d;
+        font-size: 0.9rem;
+        text-transform: uppercase;
+        letter-spacing: 1px;
+    }
+   .recipe-grid {
+    display: grid;
+    gap: 1.5rem;
+    margin-top: 2rem;
+    justify-items: center;
+    grid-template-columns: 1fr; 
+}
+@@media (min-width: 768px) {
+    .recipe-grid {
+        grid-template-columns: repeat(2, 1fr); 
+    }
+}
+@@media (min-width: 992px) {
+    .recipe-grid {
+        grid-template-columns: repeat(3, 1fr); 
+    }
+}
+.recipe-card {
+    width: 100%;
+    max-width: 417.953px;
+    height: 380px;
+    background: white;
+    border-radius: 20px;
+    overflow: hidden;
+    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
+    transition: transform 0.3s ease, box-shadow 0.3s ease;
+    position: relative;
+    cursor: pointer;
+    flex-shrink: 0;
+    box-sizing: border-box;
+}
+.recipe-card:hover {
+    transform: translateY(-8px);
+    box-shadow: 0 20px 40px rgba(0,0,0,0.15);
+}
+.recipe-card.loading {
+    pointer-events: none;
+}
+.recipe-card.loading * {
+    transition: none !important;
+    animation: none !important;
+}
+.recipe-image {
+    width: 100% !important;
+    height: 200px !important;
+    object-fit: cover;
+    background: linear-gradient(45deg, var(--nutri-green), var(--nutri-green-dark));
+    position: relative;
+    display: block !important;
+    flex-shrink: 0;
+    box-sizing: border-box;
+}
+.favorite-btn {
+    position: absolute;
+    top: 12px;
+    right: 12px;
+    background: rgba(255, 255, 255, 0.9);
+    border: none;
+    border-radius: 50%;
+    width: 40px;
+    height: 40px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    cursor: pointer;
+    transition: all 0.3s ease;
+    z-index: 10;
+    backdrop-filter: blur(10px);
+}
+.favorite-btn:hover {
+    background: rgba(255, 255, 255, 1);
+    transform: scale(1.1);
+}
+.favorite-btn i {
+    font-size: 18px;
+    color: #ef4444;
+    transition: all 0.3s ease;
+}
+.favorite-btn:hover i {
+    color: #dc2626;
+}
+.favorite-btn.active i {
+    color: #ef4444;
+    font-weight: 900;
+}
+.recipe-content {
+    padding: 1.5rem !important;
+    height: calc(100% - 200px) !important;
+    display: flex !important;
+    flex-direction: column !important;
+    box-sizing: border-box;
+    position: relative;
+    flex-shrink: 0;
+}
+.recipe-title {
+    font-size: 1.3rem !important;
+    font-weight: 700 !important;
+    color: #1f2937 !important;
+    margin-bottom: 0.5rem !important;
+    line-height: 1.3 !important;
+    transition: none !important;
+    animation: none !important;
+}
+.recipe-card .recipe-title,
+.recipe-card:hover .recipe-title,
+.recipe-card:active .recipe-title,
+.recipe-card:focus .recipe-title,
+.recipe-card.loading .recipe-title {
+    font-size: 1.3rem !important;
+    font-weight: 700 !important;
+    color: #1f2937 !important;
+    margin-bottom: 0.5rem !important;
+    line-height: 1.3 !important;
+    transition: none !important;
+    animation: none !important;
+}
+.recipe-meta {
+    display: flex;
+    align-items: center;
+    gap: 1rem;
+    margin-bottom: 1rem;
+    font-size: 0.9rem;
+    color: var(--nutri-gray);
+    flex-wrap: wrap;
+}
+.recipe-meta .rating {
+    color: #fbbf24;
+    font-weight: 600;
+}
+.recipe-meta i {
+    margin-right: 4px;
+}
+.recipe-macros {
+    display: grid;
+    grid-template-columns: repeat(4, 1fr);
+    gap: 0.5rem;
+    margin-top: 1px;
+    padding-top: 0.7rem;
+    border-top: 1px solid #eee;
+}
+.macro-item {
+    text-align: center;
+    padding: 0.5rem;
+    background: var(--nutri-light-gray);
+    border-radius: 10px;
+}
+.macro-value {
+    font-weight: 700;
+    color: var(--nutri-green-dark);
+    font-size: 1rem;
+    line-height: 1.2;
+}
+.macro-label {
+    font-size: 0.8rem;
+    color: var(--nutri-gray);
+    text-transform: uppercase;
+    font-weight: 600;
+    line-height: 1;
+}
+    .empty-state {
+        text-align: center;
+        padding: 60px 20px;
+        background: rgba(255, 255, 255, 0.8);
+        border-radius: 20px;
+        backdrop-filter: blur(10px);
+    }
+    .empty-icon {
+        font-size: 4rem;
+        color: #bdc3c7;
+        margin-bottom: 20px;
+    }
+    .empty-title {
+        font-size: 1.5rem;
+        color: #7f8c8d;
+        margin-bottom: 10px;
+    }
+    .empty-text {
+        color: #95a5a6;
+        margin-bottom: 30px;
+    }
+    .nutrition-tags {
+        display: flex;
+        flex-wrap: wrap;
+        gap: 8px;
+        margin-top: 15px;
+    }
+    .nutrition-tag {
+        background: rgba(82, 201, 107, 0.1);
+        color: #52c96b;
+        padding: 4px 12px;
+        border-radius: 12px;
+        font-size: 0.8rem;
+        font-weight: 500;
+    }
+    #modalWindow {
+    position: fixed;
+    top: 0;
+    left: 0;
+    z-index: 9999;
+    pointer-events: none;
+}
+#modalWindow .modal {
+    pointer-events: all;
+}
+.recipe-card h3.recipe-title {
+    font-size: 1.3rem !important;
+    font-weight: 700 !important;
+    color: #1f2937 !important;
+    margin-bottom: 0.5rem !important;
+    line-height: 1.3 !important;
+}
+</style>
+<body>
+<div class="container mt-5">
+    <div class="header-section">
+        <h1>My Recipes</h1>
+        <p>Manage and showcase your culinary creations. Share your favorite dishes with the NutriMatch community.</p>
+        <a href="/Recipes/Create" class="create-recipe-btn">+ Create New Recipe</a>
+    </div>
+    <div class="stats-section">
+        <div class="stat-card">
+            <div class="stat-number">@Model.Count</div>
+            <div class="stat-label">Total Recipes</div>
+        </div>
+        <div class="stat-card">
+            <div class="stat-number">@ViewBag.AverageRating</div>
+            <div class="stat-label">Avg Rating</div>
+        </div>
+    </div>
+    @if (Model != null && Model.Any())
+    {
+        <div class="recipe-grid" id="recipeGrid">
+            @foreach (var recipe in Model)
+            {
+                <div class="recipe-card" onclick="showRecipeDetails(@recipe.Id,true)" data-calories="@recipe.Calories" data-protein="@recipe.Protein" data-carbs="@recipe.Carbs" data-fat="@recipe.Fat">
+                    <img src="@recipe.ImageUrl" alt="@recipe.Title" class="recipe-image">
+                    <div class="recipe-content">
+                        <h3 class="recipe-title">@recipe.Title</h3>
+                        <div class="recipe-meta">
+                            <span class="rating">
+                                <i class="fas fa-star"></i> @recipe.Rating
+                            </span>
+                            <span><i class="fas fa-user"></i>@recipe.User.UserName</span>
+                        </div>
+                        <div class="recipe-macros">
+                            <div class="macro-item">
+                                <div class="macro-value">@recipe.Calories</div>
+                                <div class="macro-label">Cal</div>
+                            </div>
+                            <div class="macro-item">
+                                <div class="macro-value">@recipe.Protein</div>
+                                <div class="macro-label">Protein</div>
+                            </div>
+                            <div class="macro-item">
+                                <div class="macro-value">@recipe.Carbs</div>
+                                <div class="macro-label">Carbs</div>
+                            </div>
+                            <div class="macro-item">
+                                <div class="macro-value">@recipe.Fat</div>
+                                <div class="macro-label">Fats</div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            }
+        </div>
+    }
+    else
+    {
+        <div class="empty-state">
+            <div class="empty-icon">👨‍🍳</div>
+            <h3 class="empty-title">No Recipes Yet</h3>
+            <p class="empty-text">Start creating your first recipe and share your culinary masterpieces with the community!</p>
+            <a href="/Recipes/Create" class="create-recipe-btn">Create Your First Recipe</a>
+        </div>
+    }
+</div>
+    <div id="modalWindow"></div>
+    <div id="modalWindowDelete"></div>
+<script>
+    function showRecipeDetails(recipeId,isOwner) {
+    const clickedCard = event.currentTarget;
+    clickedCard.classList.add('loading');
+    fetch(`/Recipes/Details/${recipeId}/${isOwner}`)
+        .then(response => {
+            if (!response.ok) {
+                throw new Error('Network response was not ok');
+            }
+            return response.text();
+        })
+        .then(html => {
+            const modalContainer = document.getElementById('modalWindow');
+            modalContainer.innerHTML = html;
+            const modalElement = modalContainer.querySelector('.modal');
+            if (modalElement) {
+                const modal = new bootstrap.Modal(modalElement);
+                modal.show();
+                modalElement.addEventListener('hidden.bs.modal', function () {
+                    modalContainer.innerHTML = '';
+                    clickedCard.classList.remove('loading');
+                }); 
+                modalElement.addEventListener('shown.bs.modal', function () {
+                    clickedCard.classList.remove('loading');
+                });
+            } else {    
+                clickedCard.classList.remove('loading');
+            }
+        })
+        .catch(err => {
+            console.error("Failed to fetch recipe details", err);
+            alert("Failed to load recipe details. Please try again.");
+            clickedCard.classList.remove('loading');
+        });
+}
+function openDeleteModal(recipeId) {
+    const deleteButton = event.target.closest('button');
+    deleteButton.classList.add('loading');
+    const recipeModalContainer = document.getElementById('modalWindow');
+    const recipeModalElement = recipeModalContainer.querySelector('.modal');
+    const savedRecipeHtml = recipeModalContainer.innerHTML;
+    let recipeModalWasOpen = false;
+    if (recipeModalElement && recipeModalElement.classList.contains('show')) {
+        const recipeModalInstance = bootstrap.Modal.getInstance(recipeModalElement);
+        if (recipeModalInstance) {
+            recipeModalInstance.hide();
+            recipeModalWasOpen = true;
+        }
+    }
+    fetch(`/Recipes/Delete/${recipeId}`)
+        .then(response => response.text())
+        .then(html => {
+            const deleteModalContainer = document.getElementById('modalWindowDelete');
+            deleteModalContainer.innerHTML = html;
+            const deleteModalElement = deleteModalContainer.querySelector('.modal');
+            if (deleteModalElement) {
+                const deleteModal = new bootstrap.Modal(deleteModalElement);
+                deleteModal.show();
+                deleteModalElement.addEventListener('hidden.bs.modal', function () {
+                    deleteButton.classList.remove('loading');
+                    deleteModalContainer.innerHTML = '';
+                    if (recipeModalWasOpen && savedRecipeHtml.trim() !== '') {
+                        recipeModalContainer.innerHTML = savedRecipeHtml;
+                        const restoredModal = recipeModalContainer.querySelector('.modal');
+                        if (restoredModal) {
+                            const restoredInstance = new bootstrap.Modal(restoredModal);
+                            restoredInstance.show();
+                        }
+                    }
+                });
+                deleteModalElement.addEventListener('shown.bs.modal', function () {
+                    deleteButton.classList.remove('loading');
+                });
+            } else {
+                deleteButton.classList.remove('loading');
+            }
+        })
+        .catch(error => {
+            console.error('Error loading delete modal:', error);
+            deleteButton.classList.remove('loading');
+            location.href = `/Recipes/Delete/${recipeId}`;
+        });
+}
+</script>
+</body>
Index: NutriMatch/Views/Recipes/_RecipeDetailsPartial.cshtml
===================================================================
--- NutriMatch/Views/Recipes/_RecipeDetailsPartial.cshtml	(revision a8860663d8380fb13055bfa6006477787df4824f)
+++ NutriMatch/Views/Recipes/_RecipeDetailsPartial.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -1,5 +1,14 @@
 @model NutriMatch.Models.Recipe
 <link href="~/css/_RecipeDetailsPartial.css" rel="stylesheet" />
+@{
+    bool isOwner = ViewBag.IsOwner ?? false;
+    double averageRating = ViewBag.AverageRating ?? 0.0;
+    int totalRatings = ViewBag.TotalRatings ?? 0;
+    double userRating = ViewBag.UserRating ?? 0.0;
+    bool hasUserRated = ViewBag.HasUserRated ?? false;
+    bool isFavorited = ViewBag.IsFavorited ?? false;
+}
 <div class="modal fade" id="recipeModal" tabindex="-1" aria-labelledby="recipeModalLabel" aria-hidden="true">
+    @Html.AntiForgeryToken()
     <div class="modal-dialog modal-xl">
         <div class="modal-content">
@@ -13,28 +22,42 @@
                     </div>
                     <div class="recipe-info">
-                            <div>
-                                <div class="chef-badge">
-                                    <img src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-4.0.3&auto=format&fit=crop&w=50&q=80" class="chef-avatar">
-                                    Chef Milan
-                                </div>
-                                <h2 class="recipe-title-details">@Model.Title</h2>
-                                <div class="recipe-rating">
+                        <div>
+                            <div class="chef-badge">
+                                <img src="@Model.User.ProfilePictureUrl" class="chef-avatar">
+                                @Model.User.UserName
+                            </div>
+                            <h2 class="recipe-title-details">@Model.Title</h2>
+                            <div class="recipe-rating-section">
+                                <div class="current-rating">
                                     <span class="rating-label">Rating:</span>
-                                    <span class="rating-stars">
-                                        <i class="fas fa-star"></i>
-                                        <i class="fas fa-star"></i>
-                                        <i class="fas fa-star"></i>
-                                        <i class="fas fa-star"></i>
-                                        <i class="far fa-star"></i>
-                                    </span>
-                                    <span class="rating-value">(4.2)</span>
+                                    <div class="rating-display">
+                                        <div class="rating-stars" id="displayStars">
+                                            @for (int i = 1; i <= 5; i++)
+                                            {
+                                                @if (i <= Math.Floor(averageRating))
+                                                {
+                                                    <i class="fas fa-star filled" data-rating="@i"></i>
+                                                }
+                                                else if (i <= averageRating)
+                                                {
+                                                    <i class="fas fa-star-half-alt filled" data-rating="@i"></i>
+                                                }
+                                                else
+                                                {
+                                                    <i class="far fa-star" data-rating="@i"></i>
+                                                }
+                                            }
+                                        </div>
+                                        <span class="rating-value">(@averageRating.ToString("0.0"))</span>
+                                        <span class="rating-count">@totalRatings review@(totalRatings != 1 ? "s" : "")</span>
+                                    </div>
                                 </div>
                             </div>
-                            <div class="recipe-actions">
-                                <button onclick="location.href='/Recipes/Edit/@Model.Id'" class="action-btn edit-btn"  title="Edit Recipe">
+                        </div>
+                        <div class="recipe-actions">
+                            @if(isOwner){
+                            <div class="d-flex gap-2">
+                                <button onclick="location.href='/Recipes/Edit/@Model.Id'" class="action-btn edit-btn" title="Edit Recipe">
                                     <i class="fas fa-edit"></i>
-                                </button>
-                                <button class="action-btn favorite-btn-details" title="Add to Favorites">
-                                    <i class="fas fa-heart"></i>
                                 </button>
                                 <button onclick="openDeleteModal('@Model.Id')" class="action-btn delete-btn" title="Delete Recipe">
@@ -42,5 +65,32 @@
                                 </button>
                             </div>
+                            } else {
+                                        <div class="rate-recipe">
+                                            <span class="rate-label">@(hasUserRated ? "Your rating:" : "Rate this recipe:")</span>
+                                            <div class="rating-input" id="userRatingStars">
+                                                @for (int i = 1; i <= 5; i++)
+                                                {
+                                                    <i class="@(i <= userRating ? "fas" : "far") fa-star rating-star" 
+                                                       data-rating="@i" 
+                                                       onclick="rateRecipe(@i, @Model.Id)"></i>
+                                                }
+                                            </div>
+                                            @if (hasUserRated)
+                                            {
+                                                <button class="remove-rating-btn" onclick="removeRating(@Model.Id)" title="Remove your rating">
+                                                    <i class="fas fa-times"></i> Remove
+                                                </button>
+                                            }
+                                        </div>
+                                        <div> 
+                                                <button class="action-btn favorite-btn-details @(isFavorited ? "favorited" : "")" 
+                                                        onclick="toggleFavorite(@Model.Id)" 
+                                                        title="@(isFavorited ? "Remove from Favorites" : "Add to Favorites")">
+                                                <i class="far fa-heart"></i>
+                                                </button>
+                                        </div>
+                            }
                         </div>
+                    </div>
                 </div>
                 <div class="row">
@@ -83,5 +133,5 @@
                         </div>
                     </div>
-                        <div class="col-md-8">
+                    <div class="col-md-8">
                         <div class="ingredients-list">
                             <h4 class="section-title">
@@ -108,5 +158,5 @@
                                 var instructions = System.Text.Json.JsonSerializer.Deserialize<List<string>>(Model.Instructions[0]);
                             }
-                            @for(var i = 0;  i < instructions.Count; i++){
+                            @for(var i = 0; i < instructions.Count; i++){
                                 <div class="instruction-item" style="display: flex; flex-wrap: wrap; align-items: flex-start; background-color: #f8f9fa; padding: 10px; margin: 5px 0; border-radius: 8px; border-left: 4px solid #10b981;">
                                     <span class="instruction-number" style="background-color: #10b981; color: white; border-radius: 50%; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: bold; margin-right: 10px; flex-shrink: 0;">@(i + 1)</span>
@@ -122,19 +172,396 @@
     </div>
 </div>
+<style>
+.recipe-rating-section {
+    margin: 15px 0;
+}
+.current-rating {
+    margin-bottom: 10px;
+}
+.rating-display {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+    margin-top: 5px;
+}
+.rating-stars {
+    display: flex;
+    gap: 2px;
+}
+.rating-stars i {
+    font-size: 18px;
+    color: #ddd;
+    transition: color 0.2s ease;
+}
+.rating-stars i.filled {
+    color: #fbbf24;
+}
+.rating-value {
+    font-size: 14px;
+    font-weight: 600;
+    color: #374151;
+}
+.rating-count {
+    font-size: 12px;
+    color: #6b7280;
+}
+.recipe-actions {
+    padding-top: 10px;
+    border-top: 1px solid #e5e7eb;
+    display: flex;
+    justify-content: space-between;
+}
+.rate-recipe {
+    display: flex;
+    flex-direction: column;
+    gap: 8px;
+}
+.rate-label {
+    font-size: 14px;
+    font-weight: 500;
+    color: #374151;
+}
+.rating-input {
+    display: flex;
+    gap: 3px;
+}
+.rating-star {
+    font-size: 20px;
+    color: #ddd;
+    cursor: pointer;
+    transition: all 0.2s ease;
+}
+.rating-star:hover {
+    color: #fbbf24;
+    transform: scale(1.1);
+}
+.rating-star.active {
+    color: #fbbf24;
+}
+.remove-rating-btn {
+    background: none;
+    border: none;
+    color: #ef4444;
+    font-size: 12px;
+    cursor: pointer;
+    padding: 5px 0;
+    transition: color 0.2s ease;
+}
+.remove-rating-btn:hover {
+    color: #dc2626;
+    text-decoration: underline;
+}
+.favorite-btn-details {
+    background: none;
+    border: 2px solid #e5e7eb;
+    border-radius: 50%;
+    width: 45px;
+    height: 45px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    cursor: pointer;
+    transition: all 0.3s ease;
+    color: #6b7280;
+}
+.favorite-btn-details:hover {
+    border-color: #ef4444;
+    color: #ef4444;
+    transform: scale(1.05);
+}
+.favorite-btn-details.favorited {
+    background-color: #ef4444;
+    border-color: #ef4444;
+    color: white;
+}
+.favorite-btn-details.favorited:hover {
+    background-color: #dc2626;
+    border-color: #dc2626;
+}
+.favorite-btn-details i {
+    font-size: 18px;
+    transition: transform 0.2s ease;
+}
+.favorite-btn-details:hover i {
+    transform: scale(1.1);
+}
+.rating-toast {
+    position: fixed;
+    top: 20px;
+    right: 20px;
+    background: #10b981;
+    color: white;
+    padding: 12px 20px;
+    border-radius: 8px;
+    font-size: 14px;
+    z-index: 9999;
+    transform: translateX(100%);
+    transition: transform 0.3s ease;
+}
+.rating-toast.show {
+    transform: translateX(0);
+}
+.rating-toast.error {
+    background: #ef4444;
+}
+@@media (max-width: 768px) {
+    .rating-display {
+        flex-wrap: wrap;
+        gap: 5px;
+    }
+    .rate-recipe {
+        align-items: flex-start;
+    }
+}
+</style>
 <script>
-    document.querySelectorAll('.ingredient-checkbox').forEach(checkbox => {
-        checkbox.addEventListener('change', function() {
-            const label = this.nextElementSibling;
-            if (this.checked) {
-                label.style.textDecoration = 'line-through';
-                label.style.opacity = '0.6';
+document.querySelectorAll('.ingredient-checkbox').forEach(checkbox => {
+    checkbox.addEventListener('change', function() {
+        const label = this.nextElementSibling;
+        if (this.checked) {
+            label.style.textDecoration = 'line-through';
+            label.style.opacity = '0.6';
+        } else {
+            label.style.textDecoration = 'none';
+            label.style.opacity = '1';
+        }
+    });
+});
+document.getElementById('recipeModal').addEventListener('shown.bs.modal', function () {
+    this.querySelector('.modal-body').scrollTop = 0;
+});
+let isRatingInProgress = false;
+function rateRecipe(rating, recipeId) {
+    if (isRatingInProgress) return;
+    console.log(rating)
+    isRatingInProgress = true;
+    updateUserRatingDisplay(rating);
+    fetch('/Recipes/Rate', {
+        method: 'POST',
+        headers: {
+            'Content-Type': 'application/json',
+            'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]')?.value
+        },
+        body: JSON.stringify({
+            recipeId: recipeId,
+            rating: rating
+        })
+    })
+    .then(response => response.json())
+    .then(data => {
+        if (data.success) {
+            updateAverageRatingDisplay(data.averageRating, data.totalRatings);
+            showRemoveRatingButton();
+            document.querySelector('.rate-label').textContent = 'Your rating:';
+            showToast('Rating submitted successfully!', 'success');
+        } else {
+            showToast(data.message || 'Failed to submit rating', 'error');
+            revertUserRatingDisplay();
+        }
+    })
+    .catch(error => {
+        console.error('Error:', error);
+        showToast('An error occurred while submitting your rating', 'error');
+        revertUserRatingDisplay();
+    })
+    .finally(() => {
+        isRatingInProgress = false;
+    });
+}
+function removeRating(recipeId) {
+    if (isRatingInProgress) return;
+    isRatingInProgress = true;
+    fetch('/Recipes/RemoveRating', {
+        method: 'POST',
+        headers: {
+            'Content-Type': 'application/json',
+            'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]')?.value
+        },
+        body: JSON.stringify({
+            recipeId: recipeId
+        })
+    })
+    .then(response => response.json())
+    .then(data => {
+        if (data.success) {
+            updateAverageRatingDisplay(data.averageRating, data.totalRatings);
+            clearUserRatingDisplay();
+            hideRemoveRatingButton();
+            document.querySelector('.rate-label').textContent = 'Rate this recipe:';
+            showToast('Rating removed successfully!', 'success');
+        } else {
+            showToast(data.message || 'Failed to remove rating', 'error');
+        }
+    })
+    .catch(error => {
+        console.error('Error:', error);
+        showToast('An error occurred while removing your rating', 'error');
+    })
+    .finally(() => {
+        isRatingInProgress = false;
+    });
+}
+let isFavoriteInProgress = false;
+function toggleFavorite(recipeId) {
+    if (isFavoriteInProgress) return;
+    isFavoriteInProgress = true;
+    const favoriteBtn = document.querySelector('.favorite-btn-details');
+    const wasFavorited = favoriteBtn.classList.contains('favorited');
+    if (wasFavorited) {
+        favoriteBtn.classList.remove('favorited');
+        favoriteBtn.title = 'Add to Favorites';
+    } else {
+        favoriteBtn.classList.add('favorited');
+        favoriteBtn.title = 'Remove from Favorites';
+    }
+    fetch('/Recipes/ToggleFavorite', {
+        method: 'POST',
+        headers: {
+            'Content-Type': 'application/json',
+            'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]')?.value
+        },
+        body: JSON.stringify({
+            recipeId: recipeId
+        })
+    })
+    .then(response => response.json())
+    .then(data => {
+        if (data.success) {
+            if (data.isFavorited) {
+                favoriteBtn.classList.add('favorited');
+                favoriteBtn.title = 'Remove from Favorites';
+                showToast('Added to favorites!', 'success');
             } else {
-                label.style.textDecoration = 'none';
-                label.style.opacity = '1';
+                favoriteBtn.classList.remove('favorited');
+                favoriteBtn.title = 'Add to Favorites';
+                showToast('Removed from favorites!', 'success');
             }
+        } else {
+            if (wasFavorited) {
+                favoriteBtn.classList.add('favorited');
+                favoriteBtn.title = 'Remove from Favorites';
+            } else {
+                favoriteBtn.classList.remove('favorited');
+                favoriteBtn.title = 'Add to Favorites';
+            }
+            showToast(data.message || 'Failed to update favorites', 'error');
+        }
+    })
+    .catch(error => {
+        console.error('Error:', error);
+        if (wasFavorited) {
+            favoriteBtn.classList.add('favorited');
+            favoriteBtn.title = 'Remove from Favorites';
+        } else {
+            favoriteBtn.classList.remove('favorited');
+            favoriteBtn.title = 'Add to Favorites';
+        }
+        showToast('An error occurred while updating favorites', 'error');
+    })
+    .finally(() => {
+        isFavoriteInProgress = false;
+    });
+}
+function updateUserRatingDisplay(rating) {
+    const stars = document.querySelectorAll('#userRatingStars .rating-star');
+    stars.forEach((star, index) => {
+        if (index < rating) {
+            star.classList.remove('far');
+            star.classList.add('fas', 'active');
+        } else {
+            star.classList.remove('fas', 'active');
+            star.classList.add('far');
+        }
+    });
+}
+function clearUserRatingDisplay() {
+    const stars = document.querySelectorAll('#userRatingStars .rating-star');
+    stars.forEach(star => {
+        star.classList.remove('fas', 'active');
+        star.classList.add('far');
+    });
+}
+function revertUserRatingDisplay() {
+    const userRating = @userRating;
+    if (userRating > 0) {
+        updateUserRatingDisplay(userRating);
+    } else {
+        clearUserRatingDisplay();
+    }
+}
+function updateAverageRatingDisplay(averageRating, totalRatings) {
+    const displayStars = document.querySelectorAll('#displayStars i');
+    displayStars.forEach((star, index) => {
+        const starValue = index + 1;
+        star.className = '';
+        if (starValue <= Math.floor(averageRating)) {
+            star.className = 'fas fa-star filled';
+        } else if (starValue <= averageRating) {
+            star.className = 'fas fa-star-half-alt filled';
+        } else {
+            star.className = 'far fa-star';
+        }
+    });
+    document.querySelector('.rating-value').textContent = `(${averageRating.toFixed(1)})`;
+    document.querySelector('.rating-count').textContent = `${totalRatings} review${totalRatings !== 1 ? 's' : ''}`;
+}
+function showRemoveRatingButton() {
+    let removeBtn = document.querySelector('.remove-rating-btn');
+    if (!removeBtn) {
+        removeBtn = document.createElement('button');
+        removeBtn.className = 'remove-rating-btn';
+        removeBtn.innerHTML = '<i class="fas fa-times"></i> Remove';
+        removeBtn.title = 'Remove your rating';
+        removeBtn.onclick = () => removeRating(@Model.Id);
+        document.querySelector('.rate-recipe').appendChild(removeBtn);
+    }
+    removeBtn.style.display = 'block';
+}
+function hideRemoveRatingButton() {
+    const removeBtn = document.querySelector('.remove-rating-btn');
+    if (removeBtn) {
+        removeBtn.style.display = 'none';
+    }
+}
+function showToast(message, type = 'success') {
+    const existingToast = document.querySelector('.rating-toast');
+    if (existingToast) {
+        existingToast.remove();
+    }
+    const toast = document.createElement('div');
+    toast.className = `rating-toast ${type}`;
+    toast.textContent = message;
+    document.body.appendChild(toast);
+    setTimeout(() => toast.classList.add('show'), 100);
+    setTimeout(() => {
+        toast.classList.remove('show');
+        setTimeout(() => toast.remove(), 300);
+    }, 3000);
+}
+document.addEventListener('DOMContentLoaded', function() {
+    const userRatingStars = document.querySelectorAll('#userRatingStars .rating-star');
+    userRatingStars.forEach((star, index) => {
+        star.addEventListener('mouseenter', function() {
+            if (isRatingInProgress) return;
+            userRatingStars.forEach((s, i) => {
+                if (i <= index) {
+                    s.style.color = '#fbbf24';
+                } else {
+                    s.style.color = '#ddd';
+                }
+            });
         });
-    });
-    document.getElementById('recipeModal').addEventListener('shown.bs.modal', function () {
-        this.querySelector('.modal-body').scrollTop = 0;
-    });
+        star.addEventListener('mouseleave', function() {
+            if (isRatingInProgress) return;
+            const userRating = @userRating;
+            userRatingStars.forEach((s, i) => {
+                if (i < userRating) {
+                    s.style.color = '#fbbf24';
+                } else {
+                    s.style.color = '#ddd';
+                }
+            });
+        });
+    });
+});
 </script>
Index: NutriMatch/Views/Restaurants/Index.cshtml
===================================================================
--- NutriMatch/Views/Restaurants/Index.cshtml	(revision a8860663d8380fb13055bfa6006477787df4824f)
+++ NutriMatch/Views/Restaurants/Index.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -87,12 +87,4 @@
                             <div class="restaurant-name">@r.Name</div>
                             <div class="restaurant-items">@r.Description</div>
-                            <div class="restaurant-rating">
-                                <i class="fas fa-star"></i>
-                                <i class="fas fa-star"></i>
-                                <i class="fas fa-star"></i>
-                                <i class="fas fa-star-half-alt"></i>
-                                <i class="far fa-star"></i>
-                                4.2
-                            </div>
                         </div>
                     </div>
Index: NutriMatch/Views/Restaurants/_RestaurantMealsPartial.cshtml
===================================================================
--- NutriMatch/Views/Restaurants/_RestaurantMealsPartial.cshtml	(revision a8860663d8380fb13055bfa6006477787df4824f)
+++ NutriMatch/Views/Restaurants/_RestaurantMealsPartial.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -31,5 +31,5 @@
                         </span>
                         <span class="macro-badge protein">
-                            <i class="fas fa-dumbbell me-1"></i>@meal.Protein g protein
+                            <i class="fas fa-drumstick-bite me-1"></i>@meal.Protein g protein
                         </span>
                         <span class="macro-badge carbs">
@@ -37,5 +37,5 @@
                         </span>
                         <span class="macro-badge fats">
-                            <i class="fas fa-seedling me-1"></i>@meal.Fat g fats
+                            <i class="fas fa-tint me-1 "></i>@meal.Fat g fats
                         </span>
                     </div>
Index: NutriMatch/Views/Shared/_Layout.cshtml
===================================================================
--- NutriMatch/Views/Shared/_Layout.cshtml	(revision a8860663d8380fb13055bfa6006477787df4824f)
+++ NutriMatch/Views/Shared/_Layout.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -32,13 +32,22 @@
                             <a class="nav-link @(currentController == "Recipes" && currentAction == "Index" ? "active-glow" : "")" href="/Recipes" >Recipes</a>
                         </li>
-                         <li class="nav-item">
-                            <a class="nav-link @(currentController == "Recipes" && currentAction == "Create" ? "active-glow" : "")" href="/Recipes/Create">Add Recipe</a>
-                        </li>
                         <li class="nav-item">
                             <a class="nav-link @(currentController == "Restaurants" && currentAction == "Index" ? "active-glow" : "") " href="/Restaurants">Restaurants</a>
                         </li>
-                        <li class="nav-item">
-                            <a class="nav-link" href="#">My Account</a>
-                        </li>
+                        @if(User.Identity.IsAuthenticated){
+                            <li class="nav-item">
+                                <a class="nav-link @(currentController == "Recipes" && currentAction == "MyRecipes" ? "active-glow" : "")" href="/Recipes/MyRecipes">My Recipes</a>
+                            </li>
+                            <li class="nav-item">
+                                <a class="nav-link" href="/Identity/Account/MyAccount">My Account</a>
+                            </li>  
+                            @if (User.IsInRole("Admin")){
+                                <li class="nav-item">
+                                <a class="nav-link @(currentController == "Admin" && currentAction == "Index" ? "active-glow" : "")" href="/Admin">Admin Panel</a>
+                                </li>
+                            }
+                        } else {
+                            <partial name="_LoginPartial" />
+                        }
                     </ul>
                 </div>
@@ -98,4 +107,5 @@
     </footer>
     <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
+    @await RenderSectionAsync("Scripts", required: false)
 </body>
 </html>
Index: NutriMatch/Views/Shared/_LoginPartial.cshtml
===================================================================
--- NutriMatch/Views/Shared/_LoginPartial.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
+++ NutriMatch/Views/Shared/_LoginPartial.cshtml	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -0,0 +1,25 @@
+@using Microsoft.AspNetCore.Identity
+@using NutriMatch.Models
+
+@inject SignInManager<User> SignInManager
+@inject UserManager<User> UserManager
+
+<ul class="navbar-nav">
+@if (SignInManager.IsSignedIn(User))
+{
+    <li class="nav-item">
+        <a id="manage" class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @UserManager.GetUserName(User)!</a>
+    </li>
+    <li class="nav-item">
+        <form id="logoutForm" class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Action("Index", "Home", new { area = "" })">
+            <button id="logout" type="submit" class="nav-link btn btn-link text-dark border-0">Logout</button>
+        </form>
+    </li>
+}
+else
+{
+    <li class="nav-item">
+        <a class="nav-link text-dark" id="register" asp-area="Identity" asp-page="/Account/Register">Sign Up</a>
+    </li>
+}
+</ul>
Index: NutriMatch/appsettings.json
===================================================================
--- NutriMatch/appsettings.json	(revision a8860663d8380fb13055bfa6006477787df4824f)
+++ NutriMatch/appsettings.json	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -1,7 +1,7 @@
 {
   "ConnectionStrings": {
-    "DefaultConnection": "Host=localhost;Database=nutrimatch_db;Username=postgres;Password=123;Port=5432"
+    "DefaultConnection": "Host=localhost;Database=nutrimatch_db;Username=postgres;Password=123;Port=5432",
+    "ApplicationDbContextConnection": "Server=(localdb)\\mssqllocaldb;Database=NutriMatch;Trusted_Connection=True;MultipleActiveResultSets=true"
   },
-
   "Logging": {
     "LogLevel": {
Index: NutriMatch/wwwroot/css/RecipeIndex.css
===================================================================
--- NutriMatch/wwwroot/css/RecipeIndex.css	(revision a8860663d8380fb13055bfa6006477787df4824f)
+++ NutriMatch/wwwroot/css/RecipeIndex.css	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -352,2 +352,59 @@
     line-height: 1.3 !important;
 }
+
+
+
+.favorite-btn {
+    position: absolute;
+    top: 10px;
+    right: 10px;
+    background: rgba(255, 255, 255, 0.9);
+    border: none;
+    border-radius: 50%;
+    width: 40px;
+    height: 40px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    cursor: pointer;
+    transition: all 0.3s ease;
+    z-index: 2;
+    backdrop-filter: blur(10px);
+}
+
+.favorite-btn:hover {
+    background: rgba(255, 255, 255, 1);
+    transform: scale(1.1);
+    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
+}
+
+.favorite-btn i {
+    font-size: 18px;
+    transition: all 0.3s ease;
+}
+
+.favorite-btn i.far {
+    color: #6b7280;
+}
+
+.favorite-btn i.fas {
+    color: #ef4444;
+    animation: heartBeat 0.6s ease;
+}
+
+.favorite-btn:hover i.far {
+    color: #ef4444;
+}
+
+@keyframes heartBeat {
+    0% { transform: scale(1); }
+    25% { transform: scale(1.2); }
+    50% { transform: scale(1); }
+    75% { transform: scale(1.1); }
+    100% { transform: scale(1); }
+}
+
+
+.recipe-card {
+    position: relative;
+}
Index: NutriMatch/wwwroot/css/RestaurantIndex.css
===================================================================
--- NutriMatch/wwwroot/css/RestaurantIndex.css	(revision a8860663d8380fb13055bfa6006477787df4824f)
+++ NutriMatch/wwwroot/css/RestaurantIndex.css	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -30,4 +30,5 @@
             cursor: pointer;
             height: 100%;
+
         }
         
Index: NutriMatch/wwwroot/css/_Layout.css
===================================================================
--- NutriMatch/wwwroot/css/_Layout.css	(revision a8860663d8380fb13055bfa6006477787df4824f)
+++ NutriMatch/wwwroot/css/_Layout.css	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -1,19 +1,42 @@
 ﻿:root {
-            
-            --dark-green: #27AE60;
-            --light-green: #58D68D;
-            --accent-pink: #2c3534;
-            --light-pink: #bbcabe;
-            --dark-gray: #11ff00;
-            --light-gray: #ECF0F1;
-        }
+    --dark-green: #27AE60;
+    --light-green: #58D68D;
+    --accent-pink: #2c3534;
+    --light-pink: #bbcabe;
+    --dark-gray: #11ff00;
+    --light-gray: #ECF0F1;
+}
 
 
+body {
+    min-height: 100vh;
+    display: flex;
+    flex-direction: column;
+    margin: 0;
+}
+
+.container:has(main) {
+    flex: 1;
+}
+
+footer {
+    margin-top: auto;
+}
+.container:has(main) {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+}
+
+main {
+    flex: 1;
+}
+
 .navbar {
-            background: white !important;
-            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
-            padding:  0px;
-            height: 80px;
-        }
+    background: white !important;
+    box-shadow: 0 2px 10px rgba(0,0,0,0.1);
+    padding: 0px;
+    height: 80px;
+}
 
 .navbar-brand {
@@ -34,6 +57,6 @@
 
 .nav-link{
-    color: black  !important;
-    font-size: 18px  !important;
+    color: black !important;
+    font-size: 18px !important;
     margin-left: 15px;
 }
@@ -43,4 +66,6 @@
     color: white;
     padding: 4rem 0 2rem;
+    margin-top: auto;
+    flex-shrink: 0;
 }
 
Index: NutriMatch/wwwroot/css/_RecipeDetailsPartial.css
===================================================================
--- NutriMatch/wwwroot/css/_RecipeDetailsPartial.css	(revision a8860663d8380fb13055bfa6006477787df4824f)
+++ NutriMatch/wwwroot/css/_RecipeDetailsPartial.css	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -71,4 +71,7 @@
         background: #e91e63;
         color: white;
+        border-radius: 10px !important;
+        height: 40px !important;
+        width: 40px !important;
     }
 
Index: NutriMatch/wwwroot/js/RecipeCreate.js
===================================================================
--- NutriMatch/wwwroot/js/RecipeCreate.js	(revision a8860663d8380fb13055bfa6006477787df4824f)
+++ NutriMatch/wwwroot/js/RecipeCreate.js	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -383,3 +383,26 @@
         reader.readAsDataURL(file);
     }
-}    
+}
+
+function validateInstructions() {
+    const instructionsContainer = document.getElementById('instructionsList');
+    const instructionsInput = document.getElementById('selectedInstructions');
+    const hasInstructions = instructionsInput.value && 
+                           instructionsInput.value !== '[]' && 
+                           instructionsInput.value.trim() !== '';
+    
+    if (!hasInstructions) {
+        instructionsContainer.innerHTML = '<div class="items-empty error">Please add at least one instruction step</div>';
+        alert('Please fill in the instructions');
+        return false;
+    }
+    return true;
+}
+
+
+document.querySelector('form').addEventListener('submit', function(e) {
+    if (!validateInstructions()) {
+        e.preventDefault();
+        return false;
+    }
+});
Index: NutriMatch/wwwroot/js/RecipeIndex.js
===================================================================
--- NutriMatch/wwwroot/js/RecipeIndex.js	(revision a8860663d8380fb13055bfa6006477787df4824f)
+++ NutriMatch/wwwroot/js/RecipeIndex.js	(revision 4a68273d2173d196bea803f19c4d87863b81f215)
@@ -1,11 +1,7 @@
 document.addEventListener('DOMContentLoaded', function() {
     const searchInput = document.getElementById('searchInput');
-    
-    
     searchInput.addEventListener('input', function() {
         filterRecipes();
     });
-    
-    
     searchInput.addEventListener('keypress', function(e) {
         if (e.key === 'Enter') {
@@ -13,13 +9,9 @@
         }
     });
-
     filterRecipes();
 });
-
 function showRecipeDetails(recipeId) {
-
     const clickedCard = event.currentTarget;
     clickedCard.classList.add('loading');
-    
     fetch(`/Recipes/Details/${recipeId}`)
         .then(response => {
@@ -32,19 +24,26 @@
             const modalContainer = document.getElementById('modalWindow');
             modalContainer.innerHTML = html;
-            
+            const scripts = modalContainer.querySelectorAll("script");
+            scripts.forEach(script => {
+                const newScript = document.createElement("script");
+                if (script.src) {
+                    newScript.src = script.src;
+                } else {
+                    newScript.textContent = script.textContent;
+                }
+                document.body.appendChild(newScript);
+                document.body.removeChild(newScript);
+            });
             const modalElement = modalContainer.querySelector('.modal');
             if (modalElement) {
                 const modal = new bootstrap.Modal(modalElement);
                 modal.show();
-                
                 modalElement.addEventListener('hidden.bs.modal', function () {
                     modalContainer.innerHTML = '';
                     clickedCard.classList.remove('loading');
                 }); 
-                
                 modalElement.addEventListener('shown.bs.modal', function () {
                     clickedCard.classList.remove('loading');
                 });
-
             } else {    
                 clickedCard.classList.remove('loading');
@@ -56,21 +55,5 @@
             clickedCard.classList.remove('loading');
         });
-    }
-
-function toggleFavorite(button) {
-    const icon = button.querySelector('i');
-    if (icon.classList.contains('far')) {
-        icon.classList.remove('far');
-        icon.classList.add('fas');
-        button.classList.add('active');
-    } else {
-        icon.classList.remove('fas');
-        icon.classList.add('far');
-        button.classList.remove('active');
-    }
-}
-
-
-
+}
 function updateSlider(type) {
     const minSlider = document.getElementById(type + 'Min');
@@ -78,8 +61,6 @@
     const valueDisplay = document.getElementById(type + 'Value');
     const fill = document.getElementById(type + 'Fill');
-    
     let minVal = parseInt(minSlider.value);
     let maxVal = parseInt(maxSlider.value);
-    
     if (minVal > maxVal) {
         if (event.target === minSlider) {
@@ -91,20 +72,14 @@
         }
     }
-    
     valueDisplay.textContent = minVal + ' - ' + maxVal;
-    
     const min = parseInt(minSlider.min);
     const max = parseInt(minSlider.max);
     const range = max - min;
-    
     const leftPercent = ((minVal - min) / range) * 100;
     const rightPercent = ((maxVal - min) / range) * 100;
-    
     fill.style.left = leftPercent + '%';
     fill.style.width = (rightPercent - leftPercent) + '%';
-    
-    filterRecipes();
-}
-
+    filterRecipes();
+}
 function filterRecipes() {
     const calories = {
@@ -124,20 +99,16 @@
         max: parseInt(document.getElementById('fatsMax').value)
     };
-    
     const searchTerm = document.getElementById('searchInput').value.toLowerCase();
-    
     const recipeCards = document.querySelectorAll('.recipe-card');
     let visibleCount = 0;
-    
     recipeCards.forEach(card => {
         const title = card.querySelector('.recipe-title').textContent.toLowerCase();
-        
         const recipeCalories = parseInt(card.dataset.calories) || 0;
         const recipeProtein = parseInt(card.dataset.protein) || 0;
         const recipeCarbs = parseInt(card.dataset.carbs) || 0;
         const recipeFats = parseInt(card.dataset.fat) || 0;
-        
+        const favoriteButton = card.querySelector('.favorite-btn');
+        const isFavorited = favoriteButton.getAttribute('data-favorited') === 'true';
         const matchesSearch = searchTerm === '' || title.includes(searchTerm);
-        
         const matchesMacros = 
             recipeCalories >= calories.min && recipeCalories <= calories.max &&
@@ -145,6 +116,6 @@
             recipeCarbs >= carbs.min && recipeCarbs <= carbs.max &&
             recipeFats >= fats.min && recipeFats <= fats.max;
-        
-        if (matchesSearch && matchesMacros) {
+        const matchesFavorites = !showingFavoritesOnly || isFavorited;
+        if (matchesSearch && matchesMacros && matchesFavorites) {
             card.style.display = 'block';
             visibleCount++;
@@ -153,11 +124,7 @@
         }
     });
-    
     const resultsCount = document.querySelector('.results-count');
     resultsCount.innerHTML = `<i class="fas fa-utensils me-2"></i>Showing <strong>${visibleCount} recipes</strong> matching your criteria`;
 }
-
-
-
 function resetFilters() {
     document.getElementById('caloriesMin').value = 0;
@@ -170,21 +137,19 @@
     document.getElementById('fatsMax').value = 150;
     document.getElementById('searchInput').value = '';
-    
+    if (showingFavoritesOnly) {
+        toggleFavoritesFilter();
+    }
     updateSlider('calories');
     updateSlider('protein');
     updateSlider('carbs');
     updateSlider('fats');
-
-    filterRecipes();
-}
-
-function openDeleteModal(recipeId) {
+    filterRecipes();
+}
+function openDeleteModal(recipeId,isOwner) {
     const deleteButton = event.target.closest('button');
     deleteButton.classList.add('loading');
-
     const recipeModalContainer = document.getElementById('modalWindow');
     const recipeModalElement = recipeModalContainer.querySelector('.modal');
     const savedRecipeHtml = recipeModalContainer.innerHTML;
-
     let recipeModalWasOpen = false;
     if (recipeModalElement && recipeModalElement.classList.contains('show')) {
@@ -195,20 +160,16 @@
         }
     }
-
-    fetch(`/Recipes/Delete/${recipeId}`)
+    fetch(`/Recipes/Details/${recipeId}/${isOwner}`)
         .then(response => response.text())
         .then(html => {
             const deleteModalContainer = document.getElementById('modalWindowDelete');
             deleteModalContainer.innerHTML = html;
-
             const deleteModalElement = deleteModalContainer.querySelector('.modal');
             if (deleteModalElement) {
                 const deleteModal = new bootstrap.Modal(deleteModalElement);
                 deleteModal.show();
-
                 deleteModalElement.addEventListener('hidden.bs.modal', function () {
                     deleteButton.classList.remove('loading');
                     deleteModalContainer.innerHTML = '';
-
                     if (recipeModalWasOpen && savedRecipeHtml.trim() !== '') {
                         recipeModalContainer.innerHTML = savedRecipeHtml;
@@ -220,9 +181,7 @@
                     }
                 });
-
                 deleteModalElement.addEventListener('shown.bs.modal', function () {
                     deleteButton.classList.remove('loading');
                 });
-
             } else {
                 deleteButton.classList.remove('loading');
@@ -235,4 +194,80 @@
         });
 }
-
-
+async function toggleFavoriteFromIndex(button, recipeId) {
+    try {
+        const token = document.querySelector('input[name="__RequestVerificationToken"]')?.value;
+        const response = await fetch('/Recipes/ToggleFavorite', {
+            method: 'POST',
+            headers: {
+                'Content-Type': 'application/json',
+                'RequestVerificationToken': token
+            },
+            body: JSON.stringify({ recipeId: recipeId })
+        });
+        const result = await response.json();
+        if (result.success) {
+            const heartIcon = button.querySelector('i');
+            const isFavorited = result.isFavorited;
+            if (isFavorited) {
+                heartIcon.classList.remove('far');
+                heartIcon.classList.add('fas');
+                button.setAttribute('data-favorited', 'true');
+            } else {
+                heartIcon.classList.remove('fas');
+                heartIcon.classList.add('far');
+                button.setAttribute('data-favorited', 'false');
+            }
+            if (showingFavoritesOnly) {
+                setTimeout(() => filterRecipes(), 100);
+            }
+            showToast(result.message, 'success');
+        } else {
+            showToast(result.message || 'Failed to update favorite', 'error');
+        }
+    } catch (error) {
+        console.error('Error toggling favorite:', error);
+        showToast('An error occurred while updating favorites', 'error');
+    }
+}
+function showToast(message, type = 'info') {
+    const toast = document.createElement('div');
+    toast.className = `toast toast-${type}`;
+    toast.style.cssText = `
+        position: fixed;
+        top: 20px;
+        right: 20px;
+        padding: 12px 20px;
+        border-radius: 4px;
+        color: white;
+        font-weight: 500;
+        z-index: 10000;
+        opacity: 0;
+        transition: opacity 0.3s ease;
+    `;
+    const colors = {
+        success: '#10b981',
+        error: '#ef4444',
+        info: '#3b82f6'
+    };
+    toast.style.backgroundColor = colors[type] || colors.info;
+    toast.textContent = message;
+    document.body.appendChild(toast);
+    setTimeout(() => toast.style.opacity = '1', 100);
+    setTimeout(() => {
+        toast.style.opacity = '0';
+        setTimeout(() => document.body.removeChild(toast), 300);
+    }, 3000);
+}
+let showingFavoritesOnly = false;
+function toggleFavoritesFilter() {
+    const button = document.getElementById('favoritesToggle');
+    showingFavoritesOnly = !showingFavoritesOnly;
+    if (showingFavoritesOnly) {
+        button.innerHTML = '<i class="fas fa-heart me-2"></i>Show All Recipes';
+        button.className = 'btn btn-success w-100';
+    } else {
+        button.innerHTML = '<i class="fas fa-heart me-2"></i>Show Favorites Only';
+        button.className = 'btn btn-outline-success w-100';
+    }
+    filterRecipes();
+}
