diff --git a/.gitignore b/.gitignore index 52720ca..e8e8bdc 100644 --- a/.gitignore +++ b/.gitignore @@ -364,4 +364,5 @@ FodyWeavers.xsd appsettings.json appsettings.Development.json +appsettings.example.json /.idea diff --git a/AonFreelancing.csproj b/AonFreelancing.csproj index fd58373..88ae984 100644 --- a/AonFreelancing.csproj +++ b/AonFreelancing.csproj @@ -19,4 +19,8 @@ + + + + diff --git a/Contexts/MainAppContext.cs b/Contexts/MainAppContext.cs index fac806e..106f444 100644 --- a/Contexts/MainAppContext.cs +++ b/Contexts/MainAppContext.cs @@ -1,4 +1,5 @@ -using AonFreelancing.Models; + +using AonFreelancing.Models; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using System.Reflection.Emit; @@ -6,7 +7,7 @@ namespace AonFreelancing.Contexts { - public class MainAppContext(DbContextOptions contextOptions) + public class MainAppContext(DbContextOptions contextOptions) : IdentityDbContext(contextOptions) { // For TPT design, no need to define each one @@ -20,20 +21,23 @@ public class MainAppContext(DbContextOptions contextOptions) public DbSet TempUsers { get; set; } public DbSet Bids { get; set; } public DbSet Tasks { get; set; } - + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlServer("aon"); + } protected override void OnModelCreating(ModelBuilder builder) { - + // For TPT design builder.Entity().ToTable("AspNetUsers") - .HasIndex(u=>u.PhoneNumber).IsUnique(); + .HasIndex(u => u.PhoneNumber).IsUnique(); builder.Entity().ToTable("TempUser") - .HasIndex(u=>u.PhoneNumber).IsUnique(); - + .HasIndex(u => u.PhoneNumber).IsUnique(); + builder.Entity().ToTable("Freelancers"); builder.Entity().ToTable("Clients"); builder.Entity().ToTable("SystemUsers"); - builder.Entity().ToTable("otps", o => o.HasCheckConstraint("CK_CODE","LEN([Code]) = 6")); + builder.Entity().ToTable("otps", o => o.HasCheckConstraint("CK_CODE", "LEN([Code]) = 6")); //set up relationships builder.Entity().HasOne() @@ -42,11 +46,11 @@ protected override void OnModelCreating(ModelBuilder builder) .HasPrincipalKey(nameof(TempUser.PhoneNumber)); builder.Entity().ToTable("Projects", tb => tb.HasCheckConstraint("CK_PRICE_TYPE", "[PriceType] IN ('Fixed', 'PerHour')")); - + builder.Entity() .ToTable("Projects", tb => tb.HasCheckConstraint("CK_QUALIFICATION_NAME", "[QualificationName] IN ('uiux', 'frontend', 'mobile', 'backend', 'fullstack')")); builder.Entity().ToTable("Projects", tb => tb.HasCheckConstraint("CK_STATUS", "[Status] IN ('Available', 'Closed')")) - .Property(p=>p.Status).HasDefaultValue("Available"); + .Property(p => p.Status).HasDefaultValue("Available"); builder.Entity() .HasOne(b => b.Project) diff --git a/Controllers/Mobile/v1/AuthController.cs b/Controllers/Mobile/v1/AuthController.cs index b7a2d3a..7045f71 100644 --- a/Controllers/Mobile/v1/AuthController.cs +++ b/Controllers/Mobile/v1/AuthController.cs @@ -3,7 +3,7 @@ using AonFreelancing.Models.DTOs; using AonFreelancing.Models.Requests; using AonFreelancing.Models.Responses; -using AonFreelancing.Services; +using AonFreelancing.Models.Services; using AonFreelancing.Utilities; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; @@ -37,6 +37,48 @@ JwtService jwtService _jwtService = jwtService; } + + [HttpPost("RegisterByPhone")] + + public async Task RegisterPhoneNumberAsync([FromBody] RegistByPhoneNumberDTO reg) + { + var user= await _mainAppContext.TempUsers.Where(ph=>ph.PhoneNumber==reg.PhoneNumber).FirstOrDefaultAsync(); + + + if (user != null && !user.PhoneNumberConfirmed==false) + { + + return Unauthorized(CreateErrorResponse(StatusCodes.Status401Unauthorized.ToString(), "Verify Your Account First")); + } + + user = new TempUser() { PhoneNumber=reg.PhoneNumber }; + + await _mainAppContext.TempUsers.AddAsync(user); + + string otpCode = _otpManager.GenerateOtp(); + await _mainAppContext.SaveChangesAsync(); + + OTP otp = new OTP() + { + Code = otpCode, + PhoneNumber = reg.PhoneNumber, + CreatedDate = DateTime.Now, + ExpiresAt = DateTime.Now.AddMinutes(1), + }; + + + //send the otp to the specified phone number + await _otpManager.SendOTPAsync(otp.Code, reg.PhoneNumber); + await _mainAppContext.OTPs.AddAsync(otp); + await _mainAppContext.SaveChangesAsync(); + + + + return Ok(); + + + } + [HttpPost("sendVerificationCode")] public async Task SendVerificationCodeAsync([FromBody] PhoneNumberReq phoneNumberReq) { diff --git a/Controllers/Mobile/v1/FreelancersController.cs b/Controllers/Mobile/v1/FreelancersController.cs index 9a749d8..1278c6c 100644 --- a/Controllers/Mobile/v1/FreelancersController.cs +++ b/Controllers/Mobile/v1/FreelancersController.cs @@ -10,7 +10,8 @@ namespace AonFreelancing.Controllers.Mobile.v1 { - [Authorize] + [Authorize ] + [Route("api/mobile/v1/freelancers")] [ApiController] public class FreelancersController : BaseController diff --git a/Controllers/Mobile/v1/ProjectsController.cs b/Controllers/Mobile/v1/ProjectsController.cs index eae2346..437f82b 100644 --- a/Controllers/Mobile/v1/ProjectsController.cs +++ b/Controllers/Mobile/v1/ProjectsController.cs @@ -1,7 +1,9 @@  + using AonFreelancing.Contexts; using AonFreelancing.Models; using AonFreelancing.Models.DTOs; +using AonFreelancing.Models.Services; using AonFreelancing.Utilities; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; @@ -13,15 +15,16 @@ namespace AonFreelancing.Controllers.Mobile.v1 [Authorize] [Route("api/mobile/v1/projects")] [ApiController] - public class ProjectsController(MainAppContext mainAppContext, UserManager userManager) : BaseController + public class ProjectsController(MainAppContext mainAppContext, UserManager userManager,TaskService taskService) : BaseController { + [Authorize(Roles = "CLIENT")] [HttpPost] public async Task PostProjectAsync([FromBody] ProjectInputDto projectInputDto) { - if(!ModelState.IsValid) + if (!ModelState.IsValid) { - + return base.CustomBadRequest(); } var user = await userManager.GetUserAsync(HttpContext.User); @@ -40,6 +43,7 @@ public async Task PostProjectAsync([FromBody] ProjectInputDto pro Budget = projectInputDto.Budget, PriceType = projectInputDto.PriceType, CreatedAt = DateTime.Now, + }; await mainAppContext.Projects.AddAsync(project); @@ -62,12 +66,12 @@ public async Task GetClientFeedAsync( var count = await query.CountAsync(); - if(!string.IsNullOrEmpty(trimmedQuery)) + if (!string.IsNullOrEmpty(trimmedQuery)) { query = query - .Where(p=>p.Title.ToLower().Contains(trimmedQuery)); + .Where(p => p.Title.ToLower().Contains(trimmedQuery)); } - if(qualificationNames != null && qualificationNames.Count >0) + if (qualificationNames != null && qualificationNames.Count > 0) { query = query .Where(p => qualificationNames.Contains(p.QualificationName)); @@ -78,7 +82,7 @@ public async Task GetClientFeedAsync( .Take(pageSize) .Select(p => new ProjectOutDTO { - Id= p.Id, + Id = p.Id, Title = p.Title, Description = p.Description, Status = p.Status, @@ -92,10 +96,11 @@ public async Task GetClientFeedAsync( CreationTime = StringOperations.GetTimeAgo(p.CreatedAt) }) .ToListAsync(); - - return Ok(CreateSuccessResponse(new { - Total=count, - Items=projects + + return Ok(CreateSuccessResponse(new + { + Total = count, + Items = projects })); } @@ -133,7 +138,7 @@ public async Task SubmitBidAsync(int id, [FromBody] BidInputDto b FreelancerId = user.Id, ProposedPrice = bidDto.ProposedPrice, Notes = bidDto.Notes, - Status = "pending", + Status = "pending", SubmittedAt = DateTime.Now }; @@ -181,22 +186,24 @@ public async Task GetProjectDetailsAsync(int id) var orderedBids = project.Bids .OrderByDescending(b => b.ProposedPrice) - .Select(b => new BidOutDto { - Id = b.Id, - FreelancerId = b.FreelancerId, - Freelancer = new FreelancerShortOutDTO { - Id = b.FreelancerId, - Name = b.Freelancer.Name - }, - ProposedPrice = b.ProposedPrice, - Notes = b.Notes, - Status = b.Status, - SubmittedAt = b.SubmittedAt, - ApprovedAt = b.ApprovedAt - } ); - - - + .Select(b => new BidOutDto + { + Id = b.Id, + FreelancerId = b.FreelancerId, + Freelancer = new FreelancerShortOutDTO + { + Id = b.FreelancerId, + Name = b.Freelancer.Name + }, + ProposedPrice = b.ProposedPrice, + Notes = b.Notes, + Status = b.Status, + SubmittedAt = b.SubmittedAt, + ApprovedAt = b.ApprovedAt + }); + + + return Ok(CreateSuccessResponse(new { project.Id, @@ -204,7 +211,7 @@ public async Task GetProjectDetailsAsync(int id) project.Status, project.Budget, project.Duration, - project.Description, + project.Description, Bids = orderedBids })); } @@ -233,109 +240,8 @@ public async Task CreateTaskAsync(int id, [FromBody] TaskInputDto } - [Authorize(Roles = "CLIENT, FREELANCER")] - [HttpPut("tasks/{id}")] - public async Task UpdateTaskStatusAsync(int id, [FromBody] TaskStatusDto taskStatusDto) - { - var task = await mainAppContext.Tasks.FindAsync(id); - if (task == null) - { - var errorResponse = new ApiResponse - { - IsSuccess = false, - Results = null, - Errors = new List - { - new Error { Code = "404", Message = "Task not found." } - } - }; - return NotFound(errorResponse); - } - - var validStatuses = new List { "to-do", "in-progress", "in-review", "done" }; - - if (!validStatuses.Contains(taskStatusDto.NewStatus.ToLower())) - { - var errorResponse = new ApiResponse - { - IsSuccess = false, - Results = null, - Errors = new List - { - new Error { Code = "400", Message = "Invalid status provided." } - } - }; - return BadRequest(errorResponse); - } - - if (task.Status.ToLower() == "to do" && taskStatusDto.NewStatus.ToLower() != "in progress") - { - var errorResponse = new ApiResponse - { - IsSuccess = false, - Results = null, - Errors = new List - { - new Error { Code = "400", Message = "Invalid status transition from 'To Do'." } - } - }; - return BadRequest(errorResponse); - } - if (task.Status.ToLower() == "in progress" && - taskStatusDto.NewStatus.ToLower() != "in review" && taskStatusDto.NewStatus.ToLower() != "done") - { - var errorResponse = new ApiResponse - { - IsSuccess = false, - Results = null, - Errors = new List - { - new Error { Code = "400", Message = "Invalid status transition from 'In Progress'." } - } - }; - return BadRequest(errorResponse); - } - if (task.Status.ToLower() == "in review" && taskStatusDto.NewStatus.ToLower() != "done") - { - var errorResponse = new ApiResponse - { - IsSuccess = false, - Results = null, - Errors = new List - { - new Error { Code = "400", Message = "Invalid status transition from 'In Review'." } - } - }; - return BadRequest(errorResponse); - } - if (task.Status.ToLower() == "done") - { - var errorResponse = new ApiResponse - { - IsSuccess = false, - Results = null, - Errors = new List - { - new Error { Code = "400", Message = "No further status transitions allowed from 'Done'." } - } - }; - return BadRequest(errorResponse); - } - - task.Status = taskStatusDto.NewStatus; - - task.CompletedAt = taskStatusDto.NewStatus.ToLower() == "done" ? DateTime.UtcNow : (DateTime?)null; - - await mainAppContext.SaveChangesAsync(); - - var successResponse = new ApiResponse - { - IsSuccess = true, - Results = "Task status updated.", - Errors = null - }; - return Ok(successResponse); - } + + [Authorize(Roles = "CLIENT")] @@ -427,4 +333,4 @@ public async Task UploadProjectImage(int id, IFormFile file) //} } -} \ No newline at end of file +} diff --git a/Controllers/Mobile/v1/TaskController.cs b/Controllers/Mobile/v1/TaskController.cs new file mode 100644 index 0000000..17ec5c6 --- /dev/null +++ b/Controllers/Mobile/v1/TaskController.cs @@ -0,0 +1,183 @@ +using AonFreelancing.Contexts; +using AonFreelancing.Models; +using AonFreelancing.Models.DTOs; +using AonFreelancing.Models.Services; +using AonFreelancing.Utilities; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Internal; + +namespace AonFreelancing.Controllers.Mobile.v1 +{ + [Authorize] + [Route("api/mobile/v1/Task")] + [ApiController] + public class TaskController(MainAppContext mainAppContext, UserManager userManager,TaskService taskService) : BaseController + { + + + + [HttpPut("{id}/UpdateTask")] + public async TaskUpdateTask(int id, [FromBody]TaskInputDto T) + { + + if (!ModelState.IsValid) + return BadRequest(CreateErrorResponse("400","enter vaild Input")); + + var task=await mainAppContext .Tasks.Where(t=>t.Id==id).FirstOrDefaultAsync(); + if (task != null) { + task.Name = T.Name; + task.DeadlineAt=T.DeadlineAt; + task.Notes = T.Notes; + + mainAppContext.Tasks.Update(task); + mainAppContext.SaveChanges(); + + + } + + return NotFound(CreateErrorResponse("404","the Task Not Found")); + + + } + [HttpGet("{id}/GEtTask")] + public async Task GetTasks(long id,string status) + { + if (string.IsNullOrEmpty(status)) + { + + return BadRequest("Status is requird"); + + } + var task= await mainAppContext.Tasks.Where(t => t.ProjectId == id && t.Status == status).ToListAsync(); + if (task != null) { + + return Ok(CreateSuccessResponse(task)); + } + return BadRequest(CreateErrorResponse("404", "the project Not Found")); + + + } + + [HttpPut("{id}")] + public async Task UpdateTaskStatusAsync(int id, [FromBody] TaskStatusDto taskStatusDto) + { + var task = await mainAppContext.Tasks.FindAsync(id); + if (task == null) + { + var errorResponse = new ApiResponse + { + IsSuccess = false, + Results = null, + Errors = new List + { + new Error { Code = "404", Message = "Task not found." } + } + }; + return NotFound(errorResponse); + } + + var validStatuses = new List { "to-do", "in-progress", "in-review", "done" }; + + if (!validStatuses.Contains(taskStatusDto.NewStatus.ToLower())) + { + var errorResponse = new ApiResponse + { + IsSuccess = false, + Results = null, + Errors = new List + { + new Error { Code = "400", Message = "Invalid status provided." } + } + }; + return BadRequest(errorResponse); + } + + if (task.Status.ToLower() == ConstantStatus.Status_To_Do && taskStatusDto.NewStatus.ToLower() != ConstantStatus.Status_IN_Progress) + { + var errorResponse = new ApiResponse + { + IsSuccess = false, + Results = null, + Errors = new List + { + new Error { Code = "400", Message = "Invalid status transition from 'To Do'." } + } + }; + return BadRequest(errorResponse); + } + if (task.Status.ToLower() == ConstantStatus.Status_IN_Progress && + taskStatusDto.NewStatus.ToLower() != ConstantStatus.Status_review && taskStatusDto.NewStatus.ToLower() != ConstantStatus.Status_done) + { + var errorResponse = new ApiResponse + { + IsSuccess = false, + Results = null, + Errors = new List + { + new Error { Code = "400", Message = "Invalid status transition from 'In Progress'." } + } + }; + return BadRequest(errorResponse); + } + if (task.Status.ToLower() == ConstantStatus.Status_review && taskStatusDto.NewStatus.ToLower() != ConstantStatus.Status_done) + { + var errorResponse = new ApiResponse + { + IsSuccess = false, + Results = null, + Errors = new List + { + new Error { Code = "400", Message = "Invalid status transition from 'In Review'." } + } + }; + return BadRequest(errorResponse); + } + if (task.Status.ToLower() == ConstantStatus.Status_done) + { + var errorResponse = new ApiResponse + { + IsSuccess = false, + Results = null, + Errors = new List + { + new Error { Code = "400", Message = "No further status transitions allowed from 'Done'." } + } + }; + return BadRequest(errorResponse); + } + if (taskStatusDto.NewStatus.ToLower() == ConstantStatus.Status_done) + { + double precentge = taskService.GetPrecentgeOfTask(task.ProjectId); + + var project = mainAppContext.Projects.Where(p => p.Id == task.ProjectId).FirstOrDefault(); + project.prenctgeTasks=precentge; + + + mainAppContext.Projects.Update(project); + mainAppContext.SaveChanges(); + + } + task.Status = taskStatusDto.NewStatus; + + task.CompletedAt = taskStatusDto.NewStatus.ToLower() == "done" ? DateTime.UtcNow : (DateTime?)null; + + await mainAppContext.SaveChangesAsync(); + + var successResponse = new ApiResponse + { + IsSuccess = true, + Results = "Task status updated.", + Errors = null + }; + return Ok(successResponse); + } + + + + + } +} diff --git a/Migrations/20241122085257_Lecture07Mig.Designer.cs b/Migrations/20241122085257_Lecture07Mig.Designer.cs deleted file mode 100644 index e43087a..0000000 --- a/Migrations/20241122085257_Lecture07Mig.Designer.cs +++ /dev/null @@ -1,648 +0,0 @@ -// -using System; -using AonFreelancing.Contexts; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -#nullable disable - -namespace AonFreelancing.Migrations -{ - [DbContext(typeof(MainAppContext))] - [Migration("20241122085257_Lecture07Mig")] - partial class Lecture07Mig - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "8.0.10") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("AonFreelancing.Models.ApplicationRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("nvarchar(max)"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("NormalizedName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex") - .HasFilter("[NormalizedName] IS NOT NULL"); - - b.ToTable("AspNetRoles", (string)null); - }); - - modelBuilder.Entity("AonFreelancing.Models.Bid", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ApprovedAt") - .HasColumnType("datetime2"); - - b.Property("ClientId") - .HasColumnType("bigint"); - - b.Property("FreelancerId") - .HasColumnType("bigint"); - - b.Property("Notes") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("ProjectId") - .HasColumnType("int"); - - b.Property("ProposedPrice") - .HasColumnType("decimal(18,2)"); - - b.Property("Status") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("SubmittedAt") - .HasColumnType("datetime2"); - - b.Property("SystemUserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.HasIndex("ClientId"); - - b.HasIndex("FreelancerId"); - - b.HasIndex("ProjectId"); - - b.HasIndex("SystemUserId"); - - b.ToTable("Bids"); - }); - - modelBuilder.Entity("AonFreelancing.Models.OTP", b => - { - b.Property("PhoneNumber") - .HasColumnType("nvarchar(450)"); - - b.Property("Code") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("CreatedDate") - .HasColumnType("datetime2"); - - b.Property("ExpiresAt") - .HasColumnType("datetime2"); - - b.Property("IsUsed") - .HasColumnType("bit"); - - b.HasKey("PhoneNumber"); - - b.ToTable("otps", null, t => - { - t.HasCheckConstraint("CK_CODE", "LEN([Code]) = 6"); - }); - }); - - modelBuilder.Entity("AonFreelancing.Models.Project", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("Budget") - .HasColumnType("decimal(18,2)"); - - b.Property("ClientId") - .HasColumnType("bigint"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("Description") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("Duration") - .HasColumnType("int"); - - b.Property("EndDate") - .HasColumnType("datetime2"); - - b.Property("FreelancerId") - .HasColumnType("bigint"); - - b.Property("ImagePath") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("PriceType") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("QualificationName") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("StartDate") - .HasColumnType("datetime2"); - - b.Property("Status") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("nvarchar(max)") - .HasDefaultValue("Available"); - - b.Property("Title") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.HasKey("Id"); - - b.HasIndex("ClientId"); - - b.HasIndex("FreelancerId"); - - b.ToTable("Projects", null, t => - { - t.HasCheckConstraint("CK_PRICE_TYPE", "[PriceType] IN ('Fixed', 'PerHour')"); - - t.HasCheckConstraint("CK_QUALIFICATION_NAME", "[QualificationName] IN ('uiux', 'frontend', 'mobile', 'backend', 'fullstack')"); - - t.HasCheckConstraint("CK_STATUS", "[Status] IN ('Available', 'Closed')"); - }); - }); - - modelBuilder.Entity("AonFreelancing.Models.Tasks", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CompletedAt") - .HasColumnType("datetime2"); - - b.Property("DeadlineAt") - .HasColumnType("datetime2"); - - b.Property("Name") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("Notes") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("ProjectId") - .HasColumnType("int"); - - b.Property("Status") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.HasKey("Id"); - - b.HasIndex("ProjectId"); - - b.ToTable("Tasks"); - }); - - modelBuilder.Entity("AonFreelancing.Models.TempUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("PhoneNumber") - .IsRequired() - .HasColumnType("nvarchar(450)"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("bit"); - - b.HasKey("Id"); - - b.HasIndex("PhoneNumber") - .IsUnique(); - - b.ToTable("TempUser", (string)null); - }); - - modelBuilder.Entity("AonFreelancing.Models.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("About") - .HasColumnType("nvarchar(max)"); - - b.Property("AccessFailedCount") - .HasColumnType("int"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("nvarchar(max)"); - - b.Property("Email") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("EmailConfirmed") - .HasColumnType("bit"); - - b.Property("LockoutEnabled") - .HasColumnType("bit"); - - b.Property("LockoutEnd") - .HasColumnType("datetimeoffset"); - - b.Property("Name") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("NormalizedEmail") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("NormalizedUserName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("PasswordHash") - .HasColumnType("nvarchar(max)"); - - b.Property("PhoneNumber") - .HasColumnType("nvarchar(450)"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("bit"); - - b.Property("SecurityStamp") - .HasColumnType("nvarchar(max)"); - - b.Property("TwoFactorEnabled") - .HasColumnType("bit"); - - b.Property("UserName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasDatabaseName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasDatabaseName("UserNameIndex") - .HasFilter("[NormalizedUserName] IS NOT NULL"); - - b.HasIndex("PhoneNumber") - .IsUnique() - .HasFilter("[PhoneNumber] IS NOT NULL"); - - b.ToTable("AspNetUsers", (string)null); - - b.UseTptMappingStrategy(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("nvarchar(max)"); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(max)"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetRoleClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("nvarchar(max)"); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(max)"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("nvarchar(450)"); - - b.Property("ProviderKey") - .HasColumnType("nvarchar(450)"); - - b.Property("ProviderDisplayName") - .HasColumnType("nvarchar(max)"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("LoginProvider") - .HasColumnType("nvarchar(450)"); - - b.Property("Name") - .HasColumnType("nvarchar(450)"); - - b.Property("Value") - .HasColumnType("nvarchar(max)"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens", (string)null); - }); - - modelBuilder.Entity("AonFreelancing.Models.Client", b => - { - b.HasBaseType("AonFreelancing.Models.User"); - - b.Property("CompanyName") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.ToTable("Clients", (string)null); - }); - - modelBuilder.Entity("AonFreelancing.Models.Freelancer", b => - { - b.HasBaseType("AonFreelancing.Models.User"); - - b.Property("Skills") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.ToTable("Freelancers", (string)null); - }); - - modelBuilder.Entity("AonFreelancing.Models.SystemUser", b => - { - b.HasBaseType("AonFreelancing.Models.User"); - - b.Property("Permissions") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.ToTable("SystemUsers", (string)null); - }); - - modelBuilder.Entity("AonFreelancing.Models.Bid", b => - { - b.HasOne("AonFreelancing.Models.Client", null) - .WithMany("Bids") - .HasForeignKey("ClientId"); - - b.HasOne("AonFreelancing.Models.Freelancer", "Freelancer") - .WithMany("Bids") - .HasForeignKey("FreelancerId") - .OnDelete(DeleteBehavior.NoAction) - .IsRequired(); - - b.HasOne("AonFreelancing.Models.Project", "Project") - .WithMany("Bids") - .HasForeignKey("ProjectId") - .OnDelete(DeleteBehavior.NoAction) - .IsRequired(); - - b.HasOne("AonFreelancing.Models.SystemUser", null) - .WithMany("Bids") - .HasForeignKey("SystemUserId"); - - b.Navigation("Freelancer"); - - b.Navigation("Project"); - }); - - modelBuilder.Entity("AonFreelancing.Models.OTP", b => - { - b.HasOne("AonFreelancing.Models.TempUser", null) - .WithOne() - .HasForeignKey("AonFreelancing.Models.OTP", "PhoneNumber") - .HasPrincipalKey("AonFreelancing.Models.TempUser", "PhoneNumber") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("AonFreelancing.Models.Project", b => - { - b.HasOne("AonFreelancing.Models.Client", "Client") - .WithMany("Projects") - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("AonFreelancing.Models.Freelancer", "Freelancer") - .WithMany() - .HasForeignKey("FreelancerId"); - - b.Navigation("Client"); - - b.Navigation("Freelancer"); - }); - - modelBuilder.Entity("AonFreelancing.Models.Tasks", b => - { - b.HasOne("AonFreelancing.Models.Project", "Project") - .WithMany() - .HasForeignKey("ProjectId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Project"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.HasOne("AonFreelancing.Models.ApplicationRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.HasOne("AonFreelancing.Models.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.HasOne("AonFreelancing.Models.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.HasOne("AonFreelancing.Models.ApplicationRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("AonFreelancing.Models.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.HasOne("AonFreelancing.Models.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("AonFreelancing.Models.Client", b => - { - b.HasOne("AonFreelancing.Models.User", null) - .WithOne() - .HasForeignKey("AonFreelancing.Models.Client", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("AonFreelancing.Models.Freelancer", b => - { - b.HasOne("AonFreelancing.Models.User", null) - .WithOne() - .HasForeignKey("AonFreelancing.Models.Freelancer", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("AonFreelancing.Models.SystemUser", b => - { - b.HasOne("AonFreelancing.Models.User", null) - .WithOne() - .HasForeignKey("AonFreelancing.Models.SystemUser", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("AonFreelancing.Models.Project", b => - { - b.Navigation("Bids"); - }); - - modelBuilder.Entity("AonFreelancing.Models.Client", b => - { - b.Navigation("Bids"); - - b.Navigation("Projects"); - }); - - modelBuilder.Entity("AonFreelancing.Models.Freelancer", b => - { - b.Navigation("Bids"); - }); - - modelBuilder.Entity("AonFreelancing.Models.SystemUser", b => - { - b.Navigation("Bids"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Migrations/20241122085257_Lecture07Mig.cs b/Migrations/20241122085257_Lecture07Mig.cs deleted file mode 100644 index eab91a5..0000000 --- a/Migrations/20241122085257_Lecture07Mig.cs +++ /dev/null @@ -1,495 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace AonFreelancing.Migrations -{ - /// - public partial class Lecture07Mig : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "AspNetRoles", - columns: table => new - { - Id = table.Column(type: "bigint", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - NormalizedName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetRoles", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "AspNetUsers", - columns: table => new - { - Id = table.Column(type: "bigint", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - Name = table.Column(type: "nvarchar(max)", nullable: false), - About = table.Column(type: "nvarchar(max)", nullable: true), - UserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - NormalizedUserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - Email = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - NormalizedEmail = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - EmailConfirmed = table.Column(type: "bit", nullable: false), - PasswordHash = table.Column(type: "nvarchar(max)", nullable: true), - SecurityStamp = table.Column(type: "nvarchar(max)", nullable: true), - ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true), - PhoneNumber = table.Column(type: "nvarchar(450)", nullable: true), - PhoneNumberConfirmed = table.Column(type: "bit", nullable: false), - TwoFactorEnabled = table.Column(type: "bit", nullable: false), - LockoutEnd = table.Column(type: "datetimeoffset", nullable: true), - LockoutEnabled = table.Column(type: "bit", nullable: false), - AccessFailedCount = table.Column(type: "int", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUsers", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "TempUser", - columns: table => new - { - Id = table.Column(type: "bigint", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - PhoneNumber = table.Column(type: "nvarchar(450)", nullable: false), - PhoneNumberConfirmed = table.Column(type: "bit", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_TempUser", x => x.Id); - table.UniqueConstraint("AK_TempUser_PhoneNumber", x => x.PhoneNumber); - }); - - migrationBuilder.CreateTable( - name: "AspNetRoleClaims", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - RoleId = table.Column(type: "bigint", nullable: false), - ClaimType = table.Column(type: "nvarchar(max)", nullable: true), - ClaimValue = table.Column(type: "nvarchar(max)", 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(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - UserId = table.Column(type: "bigint", nullable: false), - ClaimType = table.Column(type: "nvarchar(max)", nullable: true), - ClaimValue = table.Column(type: "nvarchar(max)", 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(type: "nvarchar(450)", nullable: false), - ProviderKey = table.Column(type: "nvarchar(450)", nullable: false), - ProviderDisplayName = table.Column(type: "nvarchar(max)", nullable: true), - UserId = table.Column(type: "bigint", 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(type: "bigint", nullable: false), - RoleId = table.Column(type: "bigint", 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(type: "bigint", nullable: false), - LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), - Name = table.Column(type: "nvarchar(450)", nullable: false), - Value = table.Column(type: "nvarchar(max)", 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.CreateTable( - name: "Clients", - columns: table => new - { - Id = table.Column(type: "bigint", nullable: false), - CompanyName = table.Column(type: "nvarchar(max)", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Clients", x => x.Id); - table.ForeignKey( - name: "FK_Clients_AspNetUsers_Id", - column: x => x.Id, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "Freelancers", - columns: table => new - { - Id = table.Column(type: "bigint", nullable: false), - Skills = table.Column(type: "nvarchar(max)", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Freelancers", x => x.Id); - table.ForeignKey( - name: "FK_Freelancers_AspNetUsers_Id", - column: x => x.Id, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "SystemUsers", - columns: table => new - { - Id = table.Column(type: "bigint", nullable: false), - Permissions = table.Column(type: "nvarchar(max)", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_SystemUsers", x => x.Id); - table.ForeignKey( - name: "FK_SystemUsers_AspNetUsers_Id", - column: x => x.Id, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "otps", - columns: table => new - { - PhoneNumber = table.Column(type: "nvarchar(450)", nullable: false), - Code = table.Column(type: "nvarchar(max)", nullable: false), - CreatedDate = table.Column(type: "datetime2", nullable: false), - ExpiresAt = table.Column(type: "datetime2", nullable: false), - IsUsed = table.Column(type: "bit", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_otps", x => x.PhoneNumber); - table.CheckConstraint("CK_CODE", "LEN([Code]) = 6"); - table.ForeignKey( - name: "FK_otps_TempUser_PhoneNumber", - column: x => x.PhoneNumber, - principalTable: "TempUser", - principalColumn: "PhoneNumber", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "Projects", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - Title = table.Column(type: "nvarchar(max)", nullable: false), - Description = table.Column(type: "nvarchar(max)", nullable: false), - ClientId = table.Column(type: "bigint", nullable: false), - CreatedAt = table.Column(type: "datetime2", nullable: false), - StartDate = table.Column(type: "datetime2", nullable: true), - EndDate = table.Column(type: "datetime2", nullable: true), - PriceType = table.Column(type: "nvarchar(max)", nullable: false), - Duration = table.Column(type: "int", nullable: false), - Budget = table.Column(type: "decimal(18,2)", nullable: false), - QualificationName = table.Column(type: "nvarchar(max)", nullable: false), - Status = table.Column(type: "nvarchar(max)", nullable: false, defaultValue: "Available"), - FreelancerId = table.Column(type: "bigint", nullable: true), - ImagePath = table.Column(type: "nvarchar(max)", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Projects", x => x.Id); - table.CheckConstraint("CK_PRICE_TYPE", "[PriceType] IN ('Fixed', 'PerHour')"); - table.CheckConstraint("CK_QUALIFICATION_NAME", "[QualificationName] IN ('uiux', 'frontend', 'mobile', 'backend', 'fullstack')"); - table.CheckConstraint("CK_STATUS", "[Status] IN ('Available', 'Closed')"); - table.ForeignKey( - name: "FK_Projects_Clients_ClientId", - column: x => x.ClientId, - principalTable: "Clients", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_Projects_Freelancers_FreelancerId", - column: x => x.FreelancerId, - principalTable: "Freelancers", - principalColumn: "Id"); - }); - - migrationBuilder.CreateTable( - name: "Bids", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - ProjectId = table.Column(type: "int", nullable: false), - FreelancerId = table.Column(type: "bigint", nullable: false), - ProposedPrice = table.Column(type: "decimal(18,2)", nullable: false), - Notes = table.Column(type: "nvarchar(max)", nullable: false), - Status = table.Column(type: "nvarchar(max)", nullable: false), - SubmittedAt = table.Column(type: "datetime2", nullable: false), - ApprovedAt = table.Column(type: "datetime2", nullable: true), - ClientId = table.Column(type: "bigint", nullable: true), - SystemUserId = table.Column(type: "bigint", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Bids", x => x.Id); - table.ForeignKey( - name: "FK_Bids_Clients_ClientId", - column: x => x.ClientId, - principalTable: "Clients", - principalColumn: "Id"); - table.ForeignKey( - name: "FK_Bids_Freelancers_FreelancerId", - column: x => x.FreelancerId, - principalTable: "Freelancers", - principalColumn: "Id"); - table.ForeignKey( - name: "FK_Bids_Projects_ProjectId", - column: x => x.ProjectId, - principalTable: "Projects", - principalColumn: "Id"); - table.ForeignKey( - name: "FK_Bids_SystemUsers_SystemUserId", - column: x => x.SystemUserId, - principalTable: "SystemUsers", - principalColumn: "Id"); - }); - - migrationBuilder.CreateTable( - name: "Tasks", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - ProjectId = table.Column(type: "int", nullable: false), - Name = table.Column(type: "nvarchar(max)", nullable: false), - Status = table.Column(type: "nvarchar(max)", nullable: false), - DeadlineAt = table.Column(type: "datetime2", nullable: true), - CompletedAt = table.Column(type: "datetime2", nullable: true), - Notes = table.Column(type: "nvarchar(max)", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Tasks", x => x.Id); - table.ForeignKey( - name: "FK_Tasks_Projects_ProjectId", - column: x => x.ProjectId, - principalTable: "Projects", - 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, - filter: "[NormalizedName] IS NOT NULL"); - - 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: "IX_AspNetUsers_PhoneNumber", - table: "AspNetUsers", - column: "PhoneNumber", - unique: true, - filter: "[PhoneNumber] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UserNameIndex", - table: "AspNetUsers", - column: "NormalizedUserName", - unique: true, - filter: "[NormalizedUserName] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_Bids_ClientId", - table: "Bids", - column: "ClientId"); - - migrationBuilder.CreateIndex( - name: "IX_Bids_FreelancerId", - table: "Bids", - column: "FreelancerId"); - - migrationBuilder.CreateIndex( - name: "IX_Bids_ProjectId", - table: "Bids", - column: "ProjectId"); - - migrationBuilder.CreateIndex( - name: "IX_Bids_SystemUserId", - table: "Bids", - column: "SystemUserId"); - - migrationBuilder.CreateIndex( - name: "IX_Projects_ClientId", - table: "Projects", - column: "ClientId"); - - migrationBuilder.CreateIndex( - name: "IX_Projects_FreelancerId", - table: "Projects", - column: "FreelancerId"); - - migrationBuilder.CreateIndex( - name: "IX_Tasks_ProjectId", - table: "Tasks", - column: "ProjectId"); - - migrationBuilder.CreateIndex( - name: "IX_TempUser_PhoneNumber", - table: "TempUser", - column: "PhoneNumber", - 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: "Bids"); - - migrationBuilder.DropTable( - name: "otps"); - - migrationBuilder.DropTable( - name: "Tasks"); - - migrationBuilder.DropTable( - name: "AspNetRoles"); - - migrationBuilder.DropTable( - name: "SystemUsers"); - - migrationBuilder.DropTable( - name: "TempUser"); - - migrationBuilder.DropTable( - name: "Projects"); - - migrationBuilder.DropTable( - name: "Clients"); - - migrationBuilder.DropTable( - name: "Freelancers"); - - migrationBuilder.DropTable( - name: "AspNetUsers"); - } - } -} diff --git a/Migrations/MainAppContextModelSnapshot.cs b/Migrations/MainAppContextModelSnapshot.cs deleted file mode 100644 index 773bd99..0000000 --- a/Migrations/MainAppContextModelSnapshot.cs +++ /dev/null @@ -1,645 +0,0 @@ -// -using System; -using AonFreelancing.Contexts; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -#nullable disable - -namespace AonFreelancing.Migrations -{ - [DbContext(typeof(MainAppContext))] - partial class MainAppContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "8.0.10") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("AonFreelancing.Models.ApplicationRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("nvarchar(max)"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("NormalizedName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex") - .HasFilter("[NormalizedName] IS NOT NULL"); - - b.ToTable("AspNetRoles", (string)null); - }); - - modelBuilder.Entity("AonFreelancing.Models.Bid", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ApprovedAt") - .HasColumnType("datetime2"); - - b.Property("ClientId") - .HasColumnType("bigint"); - - b.Property("FreelancerId") - .HasColumnType("bigint"); - - b.Property("Notes") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("ProjectId") - .HasColumnType("int"); - - b.Property("ProposedPrice") - .HasColumnType("decimal(18,2)"); - - b.Property("Status") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("SubmittedAt") - .HasColumnType("datetime2"); - - b.Property("SystemUserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.HasIndex("ClientId"); - - b.HasIndex("FreelancerId"); - - b.HasIndex("ProjectId"); - - b.HasIndex("SystemUserId"); - - b.ToTable("Bids"); - }); - - modelBuilder.Entity("AonFreelancing.Models.OTP", b => - { - b.Property("PhoneNumber") - .HasColumnType("nvarchar(450)"); - - b.Property("Code") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("CreatedDate") - .HasColumnType("datetime2"); - - b.Property("ExpiresAt") - .HasColumnType("datetime2"); - - b.Property("IsUsed") - .HasColumnType("bit"); - - b.HasKey("PhoneNumber"); - - b.ToTable("otps", null, t => - { - t.HasCheckConstraint("CK_CODE", "LEN([Code]) = 6"); - }); - }); - - modelBuilder.Entity("AonFreelancing.Models.Project", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("Budget") - .HasColumnType("decimal(18,2)"); - - b.Property("ClientId") - .HasColumnType("bigint"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("Description") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("Duration") - .HasColumnType("int"); - - b.Property("EndDate") - .HasColumnType("datetime2"); - - b.Property("FreelancerId") - .HasColumnType("bigint"); - - b.Property("ImagePath") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("PriceType") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("QualificationName") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("StartDate") - .HasColumnType("datetime2"); - - b.Property("Status") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("nvarchar(max)") - .HasDefaultValue("Available"); - - b.Property("Title") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.HasKey("Id"); - - b.HasIndex("ClientId"); - - b.HasIndex("FreelancerId"); - - b.ToTable("Projects", null, t => - { - t.HasCheckConstraint("CK_PRICE_TYPE", "[PriceType] IN ('Fixed', 'PerHour')"); - - t.HasCheckConstraint("CK_QUALIFICATION_NAME", "[QualificationName] IN ('uiux', 'frontend', 'mobile', 'backend', 'fullstack')"); - - t.HasCheckConstraint("CK_STATUS", "[Status] IN ('Available', 'Closed')"); - }); - }); - - modelBuilder.Entity("AonFreelancing.Models.Tasks", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CompletedAt") - .HasColumnType("datetime2"); - - b.Property("DeadlineAt") - .HasColumnType("datetime2"); - - b.Property("Name") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("Notes") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("ProjectId") - .HasColumnType("int"); - - b.Property("Status") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.HasKey("Id"); - - b.HasIndex("ProjectId"); - - b.ToTable("Tasks"); - }); - - modelBuilder.Entity("AonFreelancing.Models.TempUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("PhoneNumber") - .IsRequired() - .HasColumnType("nvarchar(450)"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("bit"); - - b.HasKey("Id"); - - b.HasIndex("PhoneNumber") - .IsUnique(); - - b.ToTable("TempUser", (string)null); - }); - - modelBuilder.Entity("AonFreelancing.Models.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("About") - .HasColumnType("nvarchar(max)"); - - b.Property("AccessFailedCount") - .HasColumnType("int"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("nvarchar(max)"); - - b.Property("Email") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("EmailConfirmed") - .HasColumnType("bit"); - - b.Property("LockoutEnabled") - .HasColumnType("bit"); - - b.Property("LockoutEnd") - .HasColumnType("datetimeoffset"); - - b.Property("Name") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("NormalizedEmail") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("NormalizedUserName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("PasswordHash") - .HasColumnType("nvarchar(max)"); - - b.Property("PhoneNumber") - .HasColumnType("nvarchar(450)"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("bit"); - - b.Property("SecurityStamp") - .HasColumnType("nvarchar(max)"); - - b.Property("TwoFactorEnabled") - .HasColumnType("bit"); - - b.Property("UserName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasDatabaseName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasDatabaseName("UserNameIndex") - .HasFilter("[NormalizedUserName] IS NOT NULL"); - - b.HasIndex("PhoneNumber") - .IsUnique() - .HasFilter("[PhoneNumber] IS NOT NULL"); - - b.ToTable("AspNetUsers", (string)null); - - b.UseTptMappingStrategy(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("nvarchar(max)"); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(max)"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetRoleClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("nvarchar(max)"); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(max)"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("nvarchar(450)"); - - b.Property("ProviderKey") - .HasColumnType("nvarchar(450)"); - - b.Property("ProviderDisplayName") - .HasColumnType("nvarchar(max)"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("LoginProvider") - .HasColumnType("nvarchar(450)"); - - b.Property("Name") - .HasColumnType("nvarchar(450)"); - - b.Property("Value") - .HasColumnType("nvarchar(max)"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens", (string)null); - }); - - modelBuilder.Entity("AonFreelancing.Models.Client", b => - { - b.HasBaseType("AonFreelancing.Models.User"); - - b.Property("CompanyName") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.ToTable("Clients", (string)null); - }); - - modelBuilder.Entity("AonFreelancing.Models.Freelancer", b => - { - b.HasBaseType("AonFreelancing.Models.User"); - - b.Property("Skills") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.ToTable("Freelancers", (string)null); - }); - - modelBuilder.Entity("AonFreelancing.Models.SystemUser", b => - { - b.HasBaseType("AonFreelancing.Models.User"); - - b.Property("Permissions") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.ToTable("SystemUsers", (string)null); - }); - - modelBuilder.Entity("AonFreelancing.Models.Bid", b => - { - b.HasOne("AonFreelancing.Models.Client", null) - .WithMany("Bids") - .HasForeignKey("ClientId"); - - b.HasOne("AonFreelancing.Models.Freelancer", "Freelancer") - .WithMany("Bids") - .HasForeignKey("FreelancerId") - .OnDelete(DeleteBehavior.NoAction) - .IsRequired(); - - b.HasOne("AonFreelancing.Models.Project", "Project") - .WithMany("Bids") - .HasForeignKey("ProjectId") - .OnDelete(DeleteBehavior.NoAction) - .IsRequired(); - - b.HasOne("AonFreelancing.Models.SystemUser", null) - .WithMany("Bids") - .HasForeignKey("SystemUserId"); - - b.Navigation("Freelancer"); - - b.Navigation("Project"); - }); - - modelBuilder.Entity("AonFreelancing.Models.OTP", b => - { - b.HasOne("AonFreelancing.Models.TempUser", null) - .WithOne() - .HasForeignKey("AonFreelancing.Models.OTP", "PhoneNumber") - .HasPrincipalKey("AonFreelancing.Models.TempUser", "PhoneNumber") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("AonFreelancing.Models.Project", b => - { - b.HasOne("AonFreelancing.Models.Client", "Client") - .WithMany("Projects") - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("AonFreelancing.Models.Freelancer", "Freelancer") - .WithMany() - .HasForeignKey("FreelancerId"); - - b.Navigation("Client"); - - b.Navigation("Freelancer"); - }); - - modelBuilder.Entity("AonFreelancing.Models.Tasks", b => - { - b.HasOne("AonFreelancing.Models.Project", "Project") - .WithMany() - .HasForeignKey("ProjectId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Project"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.HasOne("AonFreelancing.Models.ApplicationRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.HasOne("AonFreelancing.Models.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.HasOne("AonFreelancing.Models.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.HasOne("AonFreelancing.Models.ApplicationRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("AonFreelancing.Models.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.HasOne("AonFreelancing.Models.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("AonFreelancing.Models.Client", b => - { - b.HasOne("AonFreelancing.Models.User", null) - .WithOne() - .HasForeignKey("AonFreelancing.Models.Client", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("AonFreelancing.Models.Freelancer", b => - { - b.HasOne("AonFreelancing.Models.User", null) - .WithOne() - .HasForeignKey("AonFreelancing.Models.Freelancer", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("AonFreelancing.Models.SystemUser", b => - { - b.HasOne("AonFreelancing.Models.User", null) - .WithOne() - .HasForeignKey("AonFreelancing.Models.SystemUser", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("AonFreelancing.Models.Project", b => - { - b.Navigation("Bids"); - }); - - modelBuilder.Entity("AonFreelancing.Models.Client", b => - { - b.Navigation("Bids"); - - b.Navigation("Projects"); - }); - - modelBuilder.Entity("AonFreelancing.Models.Freelancer", b => - { - b.Navigation("Bids"); - }); - - modelBuilder.Entity("AonFreelancing.Models.SystemUser", b => - { - b.Navigation("Bids"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Models/DTOs/CompletRegister.cs b/Models/DTOs/CompletRegister.cs new file mode 100644 index 0000000..23605b6 --- /dev/null +++ b/Models/DTOs/CompletRegister.cs @@ -0,0 +1,21 @@ +using System.ComponentModel.DataAnnotations; + +namespace AonFreelancing.Models.DTOs +{ + public class CompletRegister + { + + [Required] + public string Name { get; set; } + + + [EmailAddress] + [Required] + public string EmailAddress { get; set; } + [Required] + public string Password { get; set; } + [Required] + public string PhoneNumber { get; set; } + + } +} diff --git a/Models/DTOs/ProjectInputDTO.cs b/Models/DTOs/ProjectInputDTO.cs index 1234e59..e7fa3b4 100644 --- a/Models/DTOs/ProjectInputDTO.cs +++ b/Models/DTOs/ProjectInputDTO.cs @@ -16,6 +16,8 @@ public class ProjectInputDto [AllowedValues(["uiux", "mobile", "frontend", "backend", "fullstack"])] public string QualificationName { get; set; } + + public IFormFile? ImageName { get; set; } [Required] [Range(1,int.MaxValue)] public int Duration { get; set; } //Number of days diff --git a/Models/DTOs/ProjectOutDTO.cs b/Models/DTOs/ProjectOutDTO.cs index 8c9a1f2..34623ce 100644 --- a/Models/DTOs/ProjectOutDTO.cs +++ b/Models/DTOs/ProjectOutDTO.cs @@ -10,6 +10,7 @@ public class ProjectOutDTO public int Duration { get; set; } public string Title { get; set; } public string Description { get; set; } + public string Image { get; set; } public string Qualifications { get; set; } public string PriceType { get; set; } public string Status { get; set; } @@ -18,5 +19,7 @@ public class ProjectOutDTO public DateTime? StartDate { get; set; } public DateTime? EndDate { get; set; } public string? CreationTime { get; set; } + + } } diff --git a/Models/DTOs/ProjectProfileDTO.cs b/Models/DTOs/ProjectProfileDTO.cs new file mode 100644 index 0000000..287be4e --- /dev/null +++ b/Models/DTOs/ProjectProfileDTO.cs @@ -0,0 +1,16 @@ +namespace AonFreelancing.Models.DTOs +{ + public class ProjectProfileDTO + { + + + public long Id { get; set; } + + public string Name { get; set; } + public string Description { get; set; } + + public DateTime startDate { get; set; } + public DateTime endDate { get; set; } + + } +} diff --git a/Models/DTOs/RegistByPhoneNumberDTO.cs b/Models/DTOs/RegistByPhoneNumberDTO.cs new file mode 100644 index 0000000..4ec58c4 --- /dev/null +++ b/Models/DTOs/RegistByPhoneNumberDTO.cs @@ -0,0 +1,14 @@ + +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; +namespace AonFreelancing.Models.DTOs + +{ + public class RegistByPhoneNumberDTO + { + + [Required] + public string PhoneNumber { get; set; } + + } +} diff --git a/Models/DTOs/UserProfileDTO.cs b/Models/DTOs/UserProfileDTO.cs new file mode 100644 index 0000000..49f4db0 --- /dev/null +++ b/Models/DTOs/UserProfileDTO.cs @@ -0,0 +1,15 @@ +namespace AonFreelancing.Models.DTOs +{ + public class UserProfileDTO + { + public long id { get; set; } + + public string name { get; set; } + public string CompanyName { get; set; } + + public string PhoneNumber { get; set; } + public string Email { get; set; } + public List About { get; set; } + + } +} diff --git a/Models/Project.cs b/Models/Project.cs index 6d59d16..dae005a 100644 --- a/Models/Project.cs +++ b/Models/Project.cs @@ -1,4 +1,6 @@ -using System.ComponentModel.DataAnnotations; +using AonFreelancing.Models.Responses; +using AonFreelancing.Models.Services; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Diagnostics.CodeAnalysis; @@ -8,6 +10,7 @@ namespace AonFreelancing.Models [Table("Projects")] public class Project { + private readonly TaskService taskService; public int Id { get; set; } [Required] public string Title { get; set; } @@ -21,12 +24,14 @@ public class Project public DateTime CreatedAt { get; set; } public DateTime? StartDate { get; set; } + + public double prenctgeTasks { get; set; } = 0; public DateTime? EndDate { get; set; } public string PriceType { get; set; } public int Duration { get; set; } public decimal Budget { get; set; } public string QualificationName { get; set; } - public string Status { get; set; } + public string Status { get; set; } = "available"; public long? FreelancerId { get; set; } [ForeignKey("FreelancerId")] public virtual Freelancer? Freelancer { get; set; } diff --git a/Models/Requests/BidsRquset.cs b/Models/Requests/BidsRquset.cs new file mode 100644 index 0000000..de22551 --- /dev/null +++ b/Models/Requests/BidsRquset.cs @@ -0,0 +1,9 @@ +namespace AonFreelancing.Models.Requests +{ + public class BidsRequset + { + + public decimal proposed { get; set; } + public string? Nots { get; set; } + } +} diff --git a/Models/Requests/TaskRq.cs b/Models/Requests/TaskRq.cs new file mode 100644 index 0000000..65ac5e2 --- /dev/null +++ b/Models/Requests/TaskRq.cs @@ -0,0 +1,12 @@ +using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; +using System.ComponentModel.DataAnnotations; + +namespace AonFreelancing.Models.Requests +{ + public class TaskRq + { + [AllowedValues("to_do", "in_progress", "in _review", "done")] + public string Name { get; set; } + public DateTime DeadLine { get; set; } + } +} diff --git a/Models/Requests/TaskStatusRq.cs b/Models/Requests/TaskStatusRq.cs new file mode 100644 index 0000000..22bf13a --- /dev/null +++ b/Models/Requests/TaskStatusRq.cs @@ -0,0 +1,11 @@ +using System.ComponentModel.DataAnnotations; + +namespace AonFreelancing.Models.Requests +{ + public class TaskStatusRq + { + + [AllowedValues] + public string newStatus { get; set; } + } +} diff --git a/Models/Responses/TemUser.cs b/Models/Responses/TemUser.cs new file mode 100644 index 0000000..da5a578 --- /dev/null +++ b/Models/Responses/TemUser.cs @@ -0,0 +1,17 @@ +using System.ComponentModel.DataAnnotations; +using Twilio.Types; + +namespace AonFreelancing.Models.Responses +{ + public class TemUser + { + + [Key] + public long Id { get; set; } + public string? phoneNumber { get; set; } + + public bool PhoneNumberConfirm { get; set; } + + + } +} diff --git a/Models/Services/FileService.cs b/Models/Services/FileService.cs new file mode 100644 index 0000000..683e521 --- /dev/null +++ b/Models/Services/FileService.cs @@ -0,0 +1,23 @@ +using AonFreelancing.Contexts; + + +namespace AonFreelancing.Models.Services +{ + public class FileService + { + public static readonly string _uploadFolder = Path.Combine(Directory.GetCurrentDirectory(), "uploads"); + private readonly MainAppContext mainAppContext; + public FileService(MainAppContext _mainappcontext) + { + mainAppContext = _mainappcontext; + } + public async Task SaveAsync(IFormFile formFile) + { + string filePath = $"{Guid.NewGuid().ToString()}{Path.GetExtension(formFile.FileName)}"; + using Stream stream = File.Create(Path.Combine(_uploadFolder, filePath)); + await formFile.CopyToAsync(stream); + return filePath; + } + } + } + diff --git a/Services/JwtService.cs b/Models/Services/JwtService.cs similarity index 91% rename from Services/JwtService.cs rename to Models/Services/JwtService.cs index c5a4917..ced0310 100644 --- a/Services/JwtService.cs +++ b/Models/Services/JwtService.cs @@ -3,7 +3,7 @@ using System.Security.Claims; using System.Text; -namespace AonFreelancing.Services +namespace AonFreelancing.Models.Services { public class JwtService { @@ -14,7 +14,7 @@ public JwtService(IConfiguration config) _config = config; } - public string GenerateJWT(Models.User user, string role) + public string GenerateJWT(User user, string role) { var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"])); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); diff --git a/Models/Services/TaskService.cs b/Models/Services/TaskService.cs new file mode 100644 index 0000000..ad54122 --- /dev/null +++ b/Models/Services/TaskService.cs @@ -0,0 +1,27 @@ +using AonFreelancing.Contexts; +using AonFreelancing.Utilities; +using Microsoft.AspNetCore.Http.HttpResults; +using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; +namespace AonFreelancing.Models.Services +{ + public class TaskService(MainAppContext mainAppContext,UserManageruserManager) + { + + public double GetPrecentgeOfTask(int id) + { + var project = mainAppContext.Projects.Where(p => p.Id == id).FirstOrDefault(); + if (project != null) { + var toatalTask = project.Tasks.Count(); + var completeTasks = project.Tasks.Count(t => t.Status.ToLower() == ConstantStatus.Status_done.ToLower()); + var percetge = toatalTask > 0 ? (completeTasks / toatalTask) : 0; + + return percetge; + } + return 0; + } + + + + } +} diff --git a/Models/TaskEntity.cs b/Models/TaskEntity.cs index 6e9fa09..7cc8c37 100644 --- a/Models/TaskEntity.cs +++ b/Models/TaskEntity.cs @@ -1,6 +1,6 @@ namespace AonFreelancing.Models { - public class ProjectTask + public class TaskEntity { public int Id { get; set; } public int ProjectId { get; set; } diff --git a/Program.cs b/Program.cs index 001a8ac..2d046f6 100644 --- a/Program.cs +++ b/Program.cs @@ -1,14 +1,14 @@ + using AonFreelancing.Contexts; using AonFreelancing.Middlewares; using AonFreelancing.Models; -using AonFreelancing.Services; +using AonFreelancing.Models.Services; using AonFreelancing.Utilities; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; using Microsoft.IdentityModel.Tokens; using System.Text; @@ -26,6 +26,7 @@ public static void Main(string[] args) builder.Services.AddSwaggerGen(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); + builder.Services.AddSingleton(); builder.Services.AddDbContext(options => options.UseSqlServer(conf.GetConnectionString("Default"))); builder.Services.AddIdentity() .AddEntityFrameworkStores() diff --git a/Utilities/ConstantStatus.cs b/Utilities/ConstantStatus.cs new file mode 100644 index 0000000..3bc2b63 --- /dev/null +++ b/Utilities/ConstantStatus.cs @@ -0,0 +1,11 @@ +namespace AonFreelancing.Utilities +{ + public class ConstantStatus + { + + public const string Status_review = "reviwe"; + public const string Status_done = "done"; + public const string Status_IN_Progress = "in_progress"; + public const string Status_To_Do = "to_do"; + } +} diff --git a/aon.db b/aon.db new file mode 100644 index 0000000..d074bf1 Binary files /dev/null and b/aon.db differ