Compare commits
8 Commits
9b8c5412f8
...
47e2117325
| Author | SHA1 | Date | |
|---|---|---|---|
| 47e2117325 | |||
| 6e5f0fb312 | |||
| 7d54a53005 | |||
| c337c3dfd5 | |||
| 08983ba30d | |||
| 5792d2fcf4 | |||
| 6556e17146 | |||
| d3d2b4b989 |
@@ -8,12 +8,13 @@ public class ApplicationContext : DbContext
|
|||||||
: base(options)
|
: base(options)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
public DbSet<Gerbil> Gerbils { get; set; }
|
|
||||||
public DbSet<Litter> Litters { get; set; }
|
|
||||||
public DbSet<Breeder> Breeders { get; set; }
|
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
|
modelBuilder.Entity<Gerbil>().ToTable("Gerbils");
|
||||||
|
modelBuilder.Entity<Litter>().ToTable("Litters");
|
||||||
|
modelBuilder.Entity<Breeder>().ToTable("Breeders");
|
||||||
|
|
||||||
modelBuilder.Entity<Gerbil>().HasOne(entity => entity.Litter);
|
modelBuilder.Entity<Gerbil>().HasOne(entity => entity.Litter);
|
||||||
modelBuilder.Entity<Litter>().HasOne(entity => entity.Father);
|
modelBuilder.Entity<Litter>().HasOne(entity => entity.Father);
|
||||||
modelBuilder.Entity<Litter>().HasOne(entity => entity.Mother);
|
modelBuilder.Entity<Litter>().HasOne(entity => entity.Mother);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using GerbilManagerWebAPI.Models;
|
using GerbilManagerWebAPI.Models;
|
||||||
using GerbilManagerWebAPI.Repositories;
|
using GerbilManagerWebAPI.DAL;
|
||||||
using GerbilManagerWebAPI.Dtos;
|
using GerbilManagerWebAPI.Dtos;
|
||||||
|
|
||||||
using GerbilManagerWebAPI.Converter;
|
using GerbilManagerWebAPI.Converter;
|
||||||
@@ -13,20 +13,18 @@ namespace GerbilManagerWebAPI.Controllers
|
|||||||
[Route("breeders")]
|
[Route("breeders")]
|
||||||
public class BreederController : ControllerBase
|
public class BreederController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly IGerbilRepository gerbilrepository;
|
private readonly UnitOfWork unitOfWork;
|
||||||
private readonly IBreederRepository repository;
|
|
||||||
private readonly ILitterRepository litterRepository;
|
|
||||||
|
|
||||||
public BreederController(IBreederRepository repo)
|
public BreederController(UnitOfWork unitOfWork)
|
||||||
{
|
{
|
||||||
this.repository = repo;
|
this.unitOfWork = unitOfWork;
|
||||||
}
|
}
|
||||||
|
|
||||||
//GET /gerbils
|
//GET /gerbils
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public IEnumerable<BreederDto> GetBreeders()
|
public IEnumerable<BreederDto> GetBreeders()
|
||||||
{
|
{
|
||||||
var items = repository.GetBreeders().Select( breeder => breeder.AsDto());
|
var items = unitOfWork.BreederRepository.Get().Select( breeder => breeder.AsDto());
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +32,7 @@ namespace GerbilManagerWebAPI.Controllers
|
|||||||
[HttpGet("{id}")]
|
[HttpGet("{id}")]
|
||||||
public ActionResult<BreederDto> GetBreeder(Guid id)
|
public ActionResult<BreederDto> GetBreeder(Guid id)
|
||||||
{
|
{
|
||||||
var item = repository.GetBreeder(id).AsDto();
|
var item = unitOfWork.BreederRepository.GetByID(id).AsDto();
|
||||||
|
|
||||||
if(item is null)
|
if(item is null)
|
||||||
{
|
{
|
||||||
@@ -51,7 +49,8 @@ namespace GerbilManagerWebAPI.Controllers
|
|||||||
Name = dto.Name,
|
Name = dto.Name,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.repository.CreateBreeder(breeder);
|
this.unitOfWork.BreederRepository.Insert(breeder);
|
||||||
|
this.unitOfWork.Save();
|
||||||
|
|
||||||
return CreatedAtAction(nameof(GetBreeder), new { id = breeder.Id}, breeder.AsDto());
|
return CreatedAtAction(nameof(GetBreeder), new { id = breeder.Id}, breeder.AsDto());
|
||||||
}
|
}
|
||||||
@@ -59,31 +58,33 @@ namespace GerbilManagerWebAPI.Controllers
|
|||||||
[HttpPut("{id}")]
|
[HttpPut("{id}")]
|
||||||
public ActionResult UpdateBreeder(Guid id, UpdateBreederDto breederDto)
|
public ActionResult UpdateBreeder(Guid id, UpdateBreederDto breederDto)
|
||||||
{
|
{
|
||||||
var existingItem = repository.GetBreeder(id);
|
var existingItem = unitOfWork.BreederRepository.GetByID(id);
|
||||||
if(existingItem is null)
|
if(existingItem is null)
|
||||||
{
|
{
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
Breeder updatedBreeder = existingItem with{
|
Breeder updatedBreeder = existingItem with {
|
||||||
Name = breederDto.Name
|
Name = breederDto?.Name!
|
||||||
};
|
};
|
||||||
|
|
||||||
repository.UpdateBreeder(updatedBreeder);
|
unitOfWork.BreederRepository.Update(updatedBreeder);
|
||||||
|
this.unitOfWork.Save();
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpDelete("{id}")]
|
[HttpDelete("{id}")]
|
||||||
public ActionResult DeleteBreeder(Guid id)
|
public ActionResult DeleteBreeder(Guid id)
|
||||||
{
|
{
|
||||||
var existingLitter = repository.GetBreeder(id);
|
var existingLitter = unitOfWork.BreederRepository.GetByID(id);
|
||||||
|
|
||||||
if(existingLitter is null)
|
if(existingLitter is null)
|
||||||
{
|
{
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
repository.DeleteBreeder(existingLitter);
|
unitOfWork.BreederRepository.Delete(existingLitter);
|
||||||
|
this.unitOfWork.Save();
|
||||||
|
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using GerbilManagerWebAPI.Models;
|
using GerbilManagerWebAPI.Models;
|
||||||
using GerbilManagerWebAPI.Repositories;
|
using GerbilManagerWebAPI.DAL;
|
||||||
using GerbilManagerWebAPI.Dtos;
|
using GerbilManagerWebAPI.Dtos;
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@@ -11,20 +11,23 @@ namespace GerbilManagerWebAPI.Controllers
|
|||||||
[Route("gerbils")]
|
[Route("gerbils")]
|
||||||
public class GerbilsController : ControllerBase
|
public class GerbilsController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly IGerbilRepository repository;
|
private readonly UnitOfWork unitOfWork;
|
||||||
private readonly IBreederRepository breederRepository;
|
|
||||||
private readonly ILitterRepository litterRepository;
|
|
||||||
|
|
||||||
public GerbilsController(IGerbilRepository repo)
|
public GerbilsController(UnitOfWork unitOfWork)
|
||||||
{
|
{
|
||||||
this.repository = repo;
|
this.unitOfWork = unitOfWork;
|
||||||
}
|
}
|
||||||
|
|
||||||
//GET /gerbils
|
//GET /gerbils
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public IEnumerable<GerbilDto> GetGerbils()
|
public IEnumerable<GerbilDto> GetGerbils([FromQuery]string? name)
|
||||||
{
|
{
|
||||||
var items = repository.GetGerbils().Select( gerbil => gerbil.AsDto());
|
if(name != null)
|
||||||
|
{
|
||||||
|
return unitOfWork.GerbilRepository.Get(filter: x => x.Name == name).Select( gerbil => gerbil.AsDto());
|
||||||
|
}
|
||||||
|
|
||||||
|
var items = unitOfWork.GerbilRepository.Get().Select( gerbil => gerbil.AsDto());
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +35,7 @@ namespace GerbilManagerWebAPI.Controllers
|
|||||||
[HttpGet("{id}")]
|
[HttpGet("{id}")]
|
||||||
public ActionResult<GerbilDto> GetGerbil(Guid id)
|
public ActionResult<GerbilDto> GetGerbil(Guid id)
|
||||||
{
|
{
|
||||||
var item = repository.GetGerbil(id).AsDto();
|
var item = unitOfWork.GerbilRepository.GetByID(id).AsDto();
|
||||||
|
|
||||||
if(item is null)
|
if(item is null)
|
||||||
{
|
{
|
||||||
@@ -52,15 +55,16 @@ namespace GerbilManagerWebAPI.Controllers
|
|||||||
|
|
||||||
if(dto.Litter != Guid.Empty)
|
if(dto.Litter != Guid.Empty)
|
||||||
{
|
{
|
||||||
gerbil.Litter = litterRepository.GetLitter(dto.Litter);
|
gerbil.Litter = unitOfWork.LitterRepository.GetByID(dto.Litter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dto.Breeder != Guid.Empty)
|
if(dto.Breeder != Guid.Empty)
|
||||||
{
|
{
|
||||||
gerbil.Breeder = breederRepository.GetBreeder(dto.Breeder);
|
gerbil.Breeder = unitOfWork.BreederRepository.GetByID(dto.Breeder);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.repository.CreateGerbil(gerbil);
|
this.unitOfWork.GerbilRepository.Insert(gerbil);
|
||||||
|
this.unitOfWork.Save();
|
||||||
|
|
||||||
return CreatedAtAction(nameof(GetGerbil), new { id = gerbil.Id}, gerbil.AsDto());
|
return CreatedAtAction(nameof(GetGerbil), new { id = gerbil.Id}, gerbil.AsDto());
|
||||||
}
|
}
|
||||||
@@ -68,34 +72,37 @@ namespace GerbilManagerWebAPI.Controllers
|
|||||||
[HttpPut("{id}")]
|
[HttpPut("{id}")]
|
||||||
public ActionResult UpdateGerbil(Guid id, UpdateGerbilDto gerbilDto)
|
public ActionResult UpdateGerbil(Guid id, UpdateGerbilDto gerbilDto)
|
||||||
{
|
{
|
||||||
var existingItem = repository.GetGerbil(id);
|
var existingItem = unitOfWork.GerbilRepository.GetByID(id);
|
||||||
if(existingItem is null)
|
if(existingItem is null)
|
||||||
{
|
{
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
Gerbil updatedGerbil = existingItem with{
|
Gerbil updatedGerbil = existingItem with{
|
||||||
Breeder = breederRepository.GetBreeder(gerbilDto.Breeder.Id),
|
Breeder = unitOfWork.BreederRepository.GetByID(gerbilDto?.Breeder ?? Guid.Empty),
|
||||||
Litter = litterRepository.GetLitter(gerbilDto.Litter.Id),
|
Litter = unitOfWork.LitterRepository.GetByID(gerbilDto?.Litter ?? Guid.Empty),
|
||||||
Gender = (Gender) (int) gerbilDto.Gender,
|
Gender = (Gender) (int) gerbilDto?.Gender!,
|
||||||
Name = gerbilDto.Name
|
Name = gerbilDto?.Name!
|
||||||
};
|
};
|
||||||
|
|
||||||
repository.UpdateGerbil(updatedGerbil);
|
unitOfWork.GerbilRepository.Update(updatedGerbil);
|
||||||
|
this.unitOfWork.Save();
|
||||||
|
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpDelete("{id}")]
|
[HttpDelete("{id}")]
|
||||||
public ActionResult DeleteGerbil(Guid id)
|
public ActionResult DeleteGerbil(Guid id)
|
||||||
{
|
{
|
||||||
var existingGerbil = repository.GetGerbil(id);
|
var existingGerbil = unitOfWork.GerbilRepository.GetByID(id);
|
||||||
|
|
||||||
if(existingGerbil is null)
|
if(existingGerbil is null)
|
||||||
{
|
{
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
repository.DeleteGerbil(existingGerbil);
|
unitOfWork.GerbilRepository.Delete(existingGerbil);
|
||||||
|
this.unitOfWork.Save();
|
||||||
|
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using GerbilManagerWebAPI.Models;
|
using GerbilManagerWebAPI.Models;
|
||||||
using GerbilManagerWebAPI.Repositories;
|
using GerbilManagerWebAPI.DAL;
|
||||||
using GerbilManagerWebAPI.Dtos;
|
using GerbilManagerWebAPI.Dtos;
|
||||||
|
|
||||||
using GerbilManagerWebAPI.Converter;
|
using GerbilManagerWebAPI.Converter;
|
||||||
@@ -13,20 +13,18 @@ namespace GerbilManagerWebAPI.Controllers
|
|||||||
[Route("litters")]
|
[Route("litters")]
|
||||||
public class LittersController : ControllerBase
|
public class LittersController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly IGerbilRepository gerbilrepository;
|
private readonly UnitOfWork unitOfWork;
|
||||||
private readonly IBreederRepository breederRepository;
|
|
||||||
private readonly ILitterRepository repository;
|
|
||||||
|
|
||||||
public LittersController(ILitterRepository repo)
|
public LittersController(UnitOfWork unitOfWork)
|
||||||
{
|
{
|
||||||
this.repository = repo;
|
this.unitOfWork = unitOfWork;
|
||||||
}
|
}
|
||||||
|
|
||||||
//GET /gerbils
|
//GET /gerbils
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public IEnumerable<LitterDto> GetLitters()
|
public IEnumerable<LitterDto> GetLitters()
|
||||||
{
|
{
|
||||||
var items = repository.GetLitters().Select( litter => litter.AsDto());
|
var items = unitOfWork.LitterRepository.Get(includeProperties: "Father,Mother").Select( litter => litter.AsDto());
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +32,7 @@ namespace GerbilManagerWebAPI.Controllers
|
|||||||
[HttpGet("{id}")]
|
[HttpGet("{id}")]
|
||||||
public ActionResult<LitterDto> GetLitter(Guid id)
|
public ActionResult<LitterDto> GetLitter(Guid id)
|
||||||
{
|
{
|
||||||
var item = repository.GetLitter(id).AsDto();
|
var item = unitOfWork.LitterRepository.GetByID(id).AsDto();
|
||||||
|
|
||||||
if(item is null)
|
if(item is null)
|
||||||
{
|
{
|
||||||
@@ -46,16 +44,25 @@ namespace GerbilManagerWebAPI.Controllers
|
|||||||
[HttpPost()]
|
[HttpPost()]
|
||||||
public ActionResult<LitterDto> CreateLitter(CreateLitterDto dto)
|
public ActionResult<LitterDto> CreateLitter(CreateLitterDto dto)
|
||||||
{
|
{
|
||||||
|
//Sanity check if father is male and mother is female
|
||||||
|
var father = this.unitOfWork.GerbilRepository.GetByID(dto.Father ?? Guid.Empty);
|
||||||
|
var mother = this.unitOfWork.GerbilRepository.GetByID(dto.Mother ?? Guid.Empty);
|
||||||
|
if(father?.Gender == Gender.female || mother?.Gender == Gender.male)
|
||||||
|
{
|
||||||
|
return BadRequest($"The mothers gender is {mother?.Gender.ToString() ?? "unknown"} and the fathers {father?.Gender.ToString() ?? "unknown"}.");
|
||||||
|
}
|
||||||
|
|
||||||
Litter litter = new Litter{
|
Litter litter = new Litter{
|
||||||
Id = Guid.NewGuid(),
|
Id = Guid.NewGuid(),
|
||||||
Date = dto.Date,
|
Date = dto.Date,
|
||||||
Father = gerbilrepository.GetGerbil(dto.Father ?? Guid.Empty),
|
Father = this.unitOfWork.GerbilRepository.GetByID(dto.Father ?? Guid.Empty),
|
||||||
Mother = gerbilrepository.GetGerbil(dto.Mother ?? Guid.Empty),
|
Mother = this.unitOfWork.GerbilRepository.GetByID(dto.Mother ?? Guid.Empty),
|
||||||
Name = dto.Name,
|
Name = dto.Name,
|
||||||
Strength = dto.Strength
|
Strength = dto.Strength
|
||||||
};
|
};
|
||||||
|
|
||||||
this.repository.CreateLitter(litter);
|
this.unitOfWork.LitterRepository.Insert(litter);
|
||||||
|
this.unitOfWork.Save();
|
||||||
|
|
||||||
return CreatedAtAction(nameof(GetLitter), new { id = litter.Id}, litter.AsDto());
|
return CreatedAtAction(nameof(GetLitter), new { id = litter.Id}, litter.AsDto());
|
||||||
}
|
}
|
||||||
@@ -63,7 +70,7 @@ namespace GerbilManagerWebAPI.Controllers
|
|||||||
[HttpPut("{id}")]
|
[HttpPut("{id}")]
|
||||||
public ActionResult UpdateLitter(Guid id, UpdateLitterDto litterDto)
|
public ActionResult UpdateLitter(Guid id, UpdateLitterDto litterDto)
|
||||||
{
|
{
|
||||||
var existingItem = repository.GetLitter(id);
|
var existingItem = unitOfWork.LitterRepository.GetByID(id);
|
||||||
if(existingItem is null)
|
if(existingItem is null)
|
||||||
{
|
{
|
||||||
return NotFound();
|
return NotFound();
|
||||||
@@ -72,26 +79,29 @@ namespace GerbilManagerWebAPI.Controllers
|
|||||||
Litter updatedLitter = existingItem with{
|
Litter updatedLitter = existingItem with{
|
||||||
Date = litterDto.Date ?? DateTime.Now,
|
Date = litterDto.Date ?? DateTime.Now,
|
||||||
Strength = litterDto.Strength,
|
Strength = litterDto.Strength,
|
||||||
Father = gerbilrepository.GetGerbil(litterDto.Father ?? Guid.Empty),
|
Father = this.unitOfWork.GerbilRepository.GetByID(litterDto.Father ?? Guid.Empty),
|
||||||
Mother = gerbilrepository.GetGerbil(litterDto.Mother ?? Guid.Empty),
|
Mother = this.unitOfWork.GerbilRepository.GetByID(litterDto.Mother ?? Guid.Empty),
|
||||||
Name = litterDto.Name
|
Name = litterDto?.Name!
|
||||||
};
|
};
|
||||||
|
|
||||||
repository.UpdateLitter(updatedLitter);
|
unitOfWork.LitterRepository.Update(updatedLitter);
|
||||||
|
this.unitOfWork.Save();
|
||||||
|
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpDelete("{id}")]
|
[HttpDelete("{id}")]
|
||||||
public ActionResult DeleteLitter(Guid id)
|
public ActionResult DeleteLitter(Guid id)
|
||||||
{
|
{
|
||||||
var existingLitter = repository.GetLitter(id);
|
var existingLitter = unitOfWork.LitterRepository.GetByID(id);
|
||||||
|
|
||||||
if(existingLitter is null)
|
if(existingLitter is null)
|
||||||
{
|
{
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
repository.DeleteLitter(existingLitter);
|
unitOfWork.LitterRepository.Delete(existingLitter);
|
||||||
|
this.unitOfWork.Save();
|
||||||
|
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
|||||||
77
GerbilManagerWebAPI/DAL/GenericRepository.cs
Normal file
77
GerbilManagerWebAPI/DAL/GenericRepository.cs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
using System.Linq.Expressions;
|
||||||
|
using GerbilManagerWebAPI.Models;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace GerbilManagerWebAPI.DAL
|
||||||
|
{
|
||||||
|
public class GenericRepository<TEntity> where TEntity : class
|
||||||
|
{
|
||||||
|
internal ApplicationContext context;
|
||||||
|
internal DbSet<TEntity> dbSet;
|
||||||
|
|
||||||
|
public GenericRepository(ApplicationContext context)
|
||||||
|
{
|
||||||
|
this.context = context;
|
||||||
|
this.dbSet = context.Set<TEntity>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual IEnumerable<TEntity> Get(
|
||||||
|
Expression<Func<TEntity, bool>> filter = null!,
|
||||||
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null!,
|
||||||
|
string includeProperties = "")
|
||||||
|
{
|
||||||
|
IQueryable<TEntity> query = dbSet;
|
||||||
|
|
||||||
|
if (filter != null)
|
||||||
|
{
|
||||||
|
query = query.Where(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var includeProperty in includeProperties.Split
|
||||||
|
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||||
|
{
|
||||||
|
query = query.Include(includeProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orderBy != null)
|
||||||
|
{
|
||||||
|
return orderBy(query).ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return query.ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual TEntity GetByID(object id)
|
||||||
|
{
|
||||||
|
return dbSet?.Find(id)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Insert(TEntity entity)
|
||||||
|
{
|
||||||
|
dbSet.Add(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Delete(object id)
|
||||||
|
{
|
||||||
|
TEntity entityToDelete = dbSet?.Find(id)!;
|
||||||
|
if (entityToDelete is not null) Delete(entityToDelete);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Delete(TEntity entityToDelete)
|
||||||
|
{
|
||||||
|
if (context.Entry(entityToDelete).State == EntityState.Detached)
|
||||||
|
{
|
||||||
|
dbSet.Attach(entityToDelete);
|
||||||
|
}
|
||||||
|
dbSet.Remove(entityToDelete);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Update(TEntity entityToUpdate)
|
||||||
|
{
|
||||||
|
dbSet.Attach(entityToUpdate);
|
||||||
|
context.Entry(entityToUpdate).State = EntityState.Modified;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
76
GerbilManagerWebAPI/DAL/UnitOfWork.cs
Normal file
76
GerbilManagerWebAPI/DAL/UnitOfWork.cs
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
using GerbilManagerWebAPI.Models;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace GerbilManagerWebAPI.DAL
|
||||||
|
{
|
||||||
|
public class UnitOfWork : IDisposable
|
||||||
|
{
|
||||||
|
private ApplicationContext context;
|
||||||
|
private GenericRepository<Gerbil> gerbilRepository = null!;
|
||||||
|
private GenericRepository<Litter> litterRepository = null!;
|
||||||
|
private GenericRepository<Breeder> breederRepository = null!;
|
||||||
|
|
||||||
|
public GenericRepository<Gerbil> GerbilRepository
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (this.gerbilRepository == null)
|
||||||
|
{
|
||||||
|
this.gerbilRepository = new GenericRepository<Gerbil>(context);
|
||||||
|
}
|
||||||
|
return gerbilRepository;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public GenericRepository<Litter> LitterRepository
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (this.litterRepository == null)
|
||||||
|
{
|
||||||
|
this.litterRepository = new GenericRepository<Litter>(context);
|
||||||
|
}
|
||||||
|
return litterRepository;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public GenericRepository<Breeder> BreederRepository
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (this.breederRepository == null)
|
||||||
|
{
|
||||||
|
this.breederRepository = new GenericRepository<Breeder>(context);
|
||||||
|
}
|
||||||
|
return breederRepository;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnitOfWork(ApplicationContext context) => this.context = context;
|
||||||
|
|
||||||
|
public void Save()
|
||||||
|
{
|
||||||
|
context.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool disposed = false;
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (!this.disposed)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
context.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.disposed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ namespace GerbilManagerWebAPI.Dtos
|
|||||||
{
|
{
|
||||||
public string? Name { get; init; }
|
public string? Name { get; init; }
|
||||||
public GenderDto? Gender { get; init; }
|
public GenderDto? Gender { get; init; }
|
||||||
public LitterDto? Litter { get; init; }
|
public Guid? Litter { get; init; }
|
||||||
public BreederDto? Breeder { get; init; }
|
public Guid? Breeder { get; init; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,8 +11,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|||||||
namespace GerbilManagerWebAPI.Migrations
|
namespace GerbilManagerWebAPI.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(ApplicationContext))]
|
[DbContext(typeof(ApplicationContext))]
|
||||||
[Migration("20231023182219_InitialCreate")]
|
[Migration("20231030203950_initialCreate")]
|
||||||
partial class InitialCreate
|
partial class initialCreate
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
@@ -31,11 +31,12 @@ namespace GerbilManagerWebAPI.Migrations
|
|||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("uniqueidentifier");
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.ToTable("Breeders");
|
b.ToTable("Breeders", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("GerbilManagerWebAPI.Models.Gerbil", b =>
|
modelBuilder.Entity("GerbilManagerWebAPI.Models.Gerbil", b =>
|
||||||
@@ -47,13 +48,15 @@ namespace GerbilManagerWebAPI.Migrations
|
|||||||
b.Property<Guid?>("BreederId")
|
b.Property<Guid?>("BreederId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("uniqueidentifier");
|
||||||
|
|
||||||
b.Property<int>("Gender")
|
b.Property<string>("Gender")
|
||||||
.HasColumnType("int");
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.Property<Guid?>("LitterId")
|
b.Property<Guid?>("LitterId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("uniqueidentifier");
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
@@ -62,7 +65,7 @@ namespace GerbilManagerWebAPI.Migrations
|
|||||||
|
|
||||||
b.HasIndex("LitterId");
|
b.HasIndex("LitterId");
|
||||||
|
|
||||||
b.ToTable("Gerbils");
|
b.ToTable("Gerbils", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("GerbilManagerWebAPI.Models.Litter", b =>
|
modelBuilder.Entity("GerbilManagerWebAPI.Models.Litter", b =>
|
||||||
@@ -81,9 +84,10 @@ namespace GerbilManagerWebAPI.Migrations
|
|||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("uniqueidentifier");
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.Property<int>("Strength")
|
b.Property<int?>("Strength")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
@@ -92,7 +96,7 @@ namespace GerbilManagerWebAPI.Migrations
|
|||||||
|
|
||||||
b.HasIndex("MotherId");
|
b.HasIndex("MotherId");
|
||||||
|
|
||||||
b.ToTable("Litters");
|
b.ToTable("Litters", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("GerbilManagerWebAPI.Models.Gerbil", b =>
|
modelBuilder.Entity("GerbilManagerWebAPI.Models.Gerbil", b =>
|
||||||
@@ -6,7 +6,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
|
|||||||
namespace GerbilManagerWebAPI.Migrations
|
namespace GerbilManagerWebAPI.Migrations
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public partial class InitialCreate : Migration
|
public partial class initialCreate : Migration
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
@@ -16,7 +16,7 @@ namespace GerbilManagerWebAPI.Migrations
|
|||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||||
Name = table.Column<string>(type: "nvarchar(max)", nullable: true)
|
Name = table.Column<string>(type: "nvarchar(max)", nullable: false)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
@@ -28,8 +28,8 @@ namespace GerbilManagerWebAPI.Migrations
|
|||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||||
Name = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
Name = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||||
Gender = table.Column<int>(type: "nvarchar(max)", nullable: false),
|
Gender = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||||
LitterId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
|
LitterId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
|
||||||
BreederId = table.Column<Guid>(type: "uniqueidentifier", nullable: true)
|
BreederId = table.Column<Guid>(type: "uniqueidentifier", nullable: true)
|
||||||
},
|
},
|
||||||
@@ -48,9 +48,9 @@ namespace GerbilManagerWebAPI.Migrations
|
|||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||||
Name = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
Name = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||||
Date = table.Column<DateTime>(type: "datetime2", nullable: false),
|
Date = table.Column<DateTime>(type: "datetime2", nullable: false),
|
||||||
Strength = table.Column<int>(type: "int", nullable: false),
|
Strength = table.Column<int>(type: "int", nullable: true),
|
||||||
FatherId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
|
FatherId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
|
||||||
MotherId = table.Column<Guid>(type: "uniqueidentifier", nullable: true)
|
MotherId = table.Column<Guid>(type: "uniqueidentifier", nullable: true)
|
||||||
},
|
},
|
||||||
@@ -28,11 +28,12 @@ namespace GerbilManagerWebAPI.Migrations
|
|||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("uniqueidentifier");
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.ToTable("Breeders");
|
b.ToTable("Breeders", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("GerbilManagerWebAPI.Models.Gerbil", b =>
|
modelBuilder.Entity("GerbilManagerWebAPI.Models.Gerbil", b =>
|
||||||
@@ -44,13 +45,15 @@ namespace GerbilManagerWebAPI.Migrations
|
|||||||
b.Property<Guid?>("BreederId")
|
b.Property<Guid?>("BreederId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("uniqueidentifier");
|
||||||
|
|
||||||
b.Property<int>("Gender")
|
b.Property<string>("Gender")
|
||||||
.HasColumnType("int");
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.Property<Guid?>("LitterId")
|
b.Property<Guid?>("LitterId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("uniqueidentifier");
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
@@ -59,7 +62,7 @@ namespace GerbilManagerWebAPI.Migrations
|
|||||||
|
|
||||||
b.HasIndex("LitterId");
|
b.HasIndex("LitterId");
|
||||||
|
|
||||||
b.ToTable("Gerbils");
|
b.ToTable("Gerbils", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("GerbilManagerWebAPI.Models.Litter", b =>
|
modelBuilder.Entity("GerbilManagerWebAPI.Models.Litter", b =>
|
||||||
@@ -78,9 +81,10 @@ namespace GerbilManagerWebAPI.Migrations
|
|||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("uniqueidentifier");
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.Property<int>("Strength")
|
b.Property<int?>("Strength")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
@@ -89,7 +93,7 @@ namespace GerbilManagerWebAPI.Migrations
|
|||||||
|
|
||||||
b.HasIndex("MotherId");
|
b.HasIndex("MotherId");
|
||||||
|
|
||||||
b.ToTable("Litters");
|
b.ToTable("Litters", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("GerbilManagerWebAPI.Models.Gerbil", b =>
|
modelBuilder.Entity("GerbilManagerWebAPI.Models.Gerbil", b =>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using GerbilManagerWebAPI.Repositories;
|
using GerbilManagerWebAPI.DAL;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
@@ -10,7 +10,7 @@ builder.Services.AddControllers();
|
|||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
builder.Services.AddSwaggerGen();
|
builder.Services.AddSwaggerGen();
|
||||||
builder.Services.AddDbContext<ApplicationContext>(opts => opts.UseSqlServer(builder.Configuration.GetConnectionString("sqlConnection")));
|
builder.Services.AddDbContext<ApplicationContext>(opts => opts.UseSqlServer(builder.Configuration.GetConnectionString("sqlConnection")));
|
||||||
builder.Services.AddScoped<IGerbilRepository, EFGerbilRepository>();
|
builder.Services.AddScoped<UnitOfWork>();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
using GerbilManagerWebAPI.Models;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace GerbilManagerWebAPI.Repositories
|
|
||||||
{
|
|
||||||
public class EFGerbilRepository : IGerbilRepository
|
|
||||||
{
|
|
||||||
private readonly ApplicationContext context;
|
|
||||||
public EFGerbilRepository(ApplicationContext context)
|
|
||||||
{
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CreateGerbil(Gerbil gerbil)
|
|
||||||
{
|
|
||||||
context.Gerbils.Add(gerbil);
|
|
||||||
context.SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DeleteGerbil(Gerbil gerbil)
|
|
||||||
{
|
|
||||||
context.Gerbils.Remove(gerbil);
|
|
||||||
context.SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Gerbil GetGerbil(Guid id)
|
|
||||||
{
|
|
||||||
return context.Gerbils.Where(entity => entity.Id == id).First();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<Gerbil> GetGerbils()
|
|
||||||
{
|
|
||||||
return context.Gerbils.ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateGerbil(Gerbil gerbil)
|
|
||||||
{
|
|
||||||
context.Gerbils.Update(gerbil);
|
|
||||||
context.SaveChanges();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
using GerbilManagerWebAPI.Models;
|
|
||||||
|
|
||||||
namespace GerbilManagerWebAPI.Repositories
|
|
||||||
{
|
|
||||||
public interface IBreederRepository
|
|
||||||
{
|
|
||||||
IEnumerable<Breeder> GetBreeders();
|
|
||||||
|
|
||||||
Breeder GetBreeder(Guid id);
|
|
||||||
|
|
||||||
void CreateBreeder(Breeder breeder);
|
|
||||||
|
|
||||||
void UpdateBreeder(Breeder breeder);
|
|
||||||
|
|
||||||
void DeleteBreeder(Breeder breeder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
using GerbilManagerWebAPI.Models;
|
|
||||||
|
|
||||||
namespace GerbilManagerWebAPI.Repositories
|
|
||||||
{
|
|
||||||
public interface IGerbilRepository
|
|
||||||
{
|
|
||||||
IEnumerable<Gerbil> GetGerbils();
|
|
||||||
|
|
||||||
Gerbil GetGerbil(Guid id);
|
|
||||||
|
|
||||||
void CreateGerbil(Gerbil gerbil);
|
|
||||||
|
|
||||||
void UpdateGerbil(Gerbil gerbil);
|
|
||||||
|
|
||||||
void DeleteGerbil(Gerbil gerilb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
using GerbilManagerWebAPI.Models;
|
|
||||||
|
|
||||||
namespace GerbilManagerWebAPI.Repositories
|
|
||||||
{
|
|
||||||
public interface ILitterRepository
|
|
||||||
{
|
|
||||||
IEnumerable<Litter> GetLitters();
|
|
||||||
|
|
||||||
Litter GetLitter(Guid id);
|
|
||||||
|
|
||||||
void CreateLitter(Litter litter);
|
|
||||||
void UpdateLitter(Litter litter);
|
|
||||||
void DeleteLitter(Litter litter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
using GerbilManagerWebAPI.Models;
|
|
||||||
|
|
||||||
namespace GerbilManagerWebAPI.Repositories
|
|
||||||
{
|
|
||||||
public class InMemGerbilRepository : IGerbilRepository
|
|
||||||
{
|
|
||||||
private readonly List<Gerbil> _gerbilList = new()
|
|
||||||
{
|
|
||||||
new Gerbil() {Id = Guid.NewGuid(), Name = "Blacky", Breeder = null, Litter = null, Gender = Gender.unknown},
|
|
||||||
new Gerbil() {Id = Guid.NewGuid(), Name = "Coocky", Breeder = null, Litter = null, Gender = Gender.male},
|
|
||||||
new Gerbil() {Id = Guid.NewGuid(), Name = "Lazy", Breeder = null, Litter = null, Gender = Gender.female}
|
|
||||||
};
|
|
||||||
|
|
||||||
public IEnumerable<Gerbil> GetGerbils()
|
|
||||||
{
|
|
||||||
return _gerbilList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Gerbil GetGerbil(Guid id) => _gerbilList.SingleOrDefault(x => x.Id == id);
|
|
||||||
|
|
||||||
public void CreateGerbil(Gerbil gerbil)
|
|
||||||
{
|
|
||||||
_gerbilList.Add(gerbil);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateGerbil(Gerbil gerbil)
|
|
||||||
{
|
|
||||||
var index = this._gerbilList.FindIndex(existingGerbil => existingGerbil.Id == gerbil.Id);
|
|
||||||
_gerbilList[index] = gerbil;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DeleteGerbil(Gerbil gerbil)
|
|
||||||
{
|
|
||||||
var index = this._gerbilList.FindIndex(existingGerbil => existingGerbil.Id == gerbil.Id);
|
|
||||||
_gerbilList.RemoveAt(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -11,6 +11,10 @@ dotnet ef database update
|
|||||||
## Create an migration script
|
## Create an migration script
|
||||||
dotnet ef migrations add <name>
|
dotnet ef migrations add <name>
|
||||||
|
|
||||||
|
## Docker
|
||||||
|
### force compose rebuild
|
||||||
|
docker-compose build --no-cache
|
||||||
|
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
- Backup docker volume database
|
- Backup docker volume database
|
||||||
|
|||||||
@@ -4,7 +4,17 @@ version: '3.4'
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
|
|
||||||
# frontend:
|
frontend:
|
||||||
|
image: gerbilmanagernextjs
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: gerbil-manager-nextjs/Dockerfile
|
||||||
|
ports:
|
||||||
|
- 3000:3000
|
||||||
|
networks:
|
||||||
|
- net1
|
||||||
|
depends_on:
|
||||||
|
- backend
|
||||||
|
|
||||||
backend:
|
backend:
|
||||||
image: gerbilmanagerwebapi
|
image: gerbilmanagerwebapi
|
||||||
|
|||||||
3
gerbil-manager-nextjs/.eslintrc.json
Normal file
3
gerbil-manager-nextjs/.eslintrc.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"extends": "next/core-web-vitals"
|
||||||
|
}
|
||||||
36
gerbil-manager-nextjs/.gitignore
vendored
Normal file
36
gerbil-manager-nextjs/.gitignore
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.js
|
||||||
|
.yarn/install-state.gz
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# next.js
|
||||||
|
/.next/
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env*.local
|
||||||
|
|
||||||
|
# vercel
|
||||||
|
.vercel
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
next-env.d.ts
|
||||||
63
gerbil-manager-nextjs/Dockerfile
Normal file
63
gerbil-manager-nextjs/Dockerfile
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
FROM node:18-alpine AS base
|
||||||
|
|
||||||
|
# Install dependencies only when needed
|
||||||
|
FROM base AS deps
|
||||||
|
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
|
||||||
|
RUN apk add --no-cache libc6-compat
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install dependencies based on the preferred package manager
|
||||||
|
COPY gerbil-manager-nextjs/package.json gerbil-manager-nextjs/package-lock.json* ./
|
||||||
|
RUN \
|
||||||
|
if [ -f package-lock.json ]; then npm ci; \
|
||||||
|
else echo "Lockfile not found." && exit 1; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Rebuild the source code only when needed
|
||||||
|
FROM base AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
|
COPY gerbil-manager-nextjs/ .
|
||||||
|
|
||||||
|
# Next.js collects completely anonymous telemetry data about general usage.
|
||||||
|
# Learn more here: https://nextjs.org/telemetry
|
||||||
|
# Uncomment the following line in case you want to disable telemetry during the build.
|
||||||
|
ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
|
|
||||||
|
# RUN yarn build
|
||||||
|
|
||||||
|
# If using npm comment out above and use below instead
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# Production image, copy all the files and run next
|
||||||
|
FROM base AS runner
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV NODE_ENV production
|
||||||
|
# Uncomment the following line in case you want to disable telemetry during runtime.
|
||||||
|
# ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
|
|
||||||
|
RUN addgroup --system --gid 1001 nodejs
|
||||||
|
RUN adduser --system --uid 1001 nextjs
|
||||||
|
|
||||||
|
COPY --from=builder /app/public ./public
|
||||||
|
|
||||||
|
# Set the correct permission for prerender cache
|
||||||
|
RUN mkdir .next
|
||||||
|
RUN chown nextjs:nodejs .next
|
||||||
|
|
||||||
|
# Automatically leverage output traces to reduce image size
|
||||||
|
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||||
|
|
||||||
|
USER nextjs
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
ENV PORT 3000
|
||||||
|
# set hostname to localhost
|
||||||
|
ENV HOSTNAME "0.0.0.0"
|
||||||
|
|
||||||
|
CMD ["node", "server.js"]
|
||||||
40
gerbil-manager-nextjs/README.md
Normal file
40
gerbil-manager-nextjs/README.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
First, run the development server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
# or
|
||||||
|
yarn dev
|
||||||
|
# or
|
||||||
|
pnpm dev
|
||||||
|
# or
|
||||||
|
bun dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||||
|
|
||||||
|
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||||
|
|
||||||
|
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
|
||||||
|
|
||||||
|
## Learn More
|
||||||
|
|
||||||
|
To learn more about Next.js, take a look at the following resources:
|
||||||
|
|
||||||
|
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||||
|
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||||
|
|
||||||
|
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
||||||
|
|
||||||
|
## Deploy on Vercel
|
||||||
|
|
||||||
|
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||||
|
|
||||||
|
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
||||||
|
|
||||||
|
## Inspiration
|
||||||
|
|
||||||
|
[SideBar](https://tailwindcomponents.com/component/sub-menu-sidebar)
|
||||||
6
gerbil-manager-nextjs/next.config.js
Normal file
6
gerbil-manager-nextjs/next.config.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/** @type {import('next').NextConfig} */
|
||||||
|
const nextConfig = {}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
output: 'standalone'
|
||||||
|
}
|
||||||
4356
gerbil-manager-nextjs/package-lock.json
generated
Normal file
4356
gerbil-manager-nextjs/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
27
gerbil-manager-nextjs/package.json
Normal file
27
gerbil-manager-nextjs/package.json
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "gerbil-manager-nextjs",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "next dev",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start",
|
||||||
|
"lint": "next lint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"react": "^18",
|
||||||
|
"react-dom": "^18",
|
||||||
|
"next": "14.0.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5",
|
||||||
|
"@types/node": "^20",
|
||||||
|
"@types/react": "^18",
|
||||||
|
"@types/react-dom": "^18",
|
||||||
|
"autoprefixer": "^10.0.1",
|
||||||
|
"postcss": "^8",
|
||||||
|
"tailwindcss": "^3.3.0",
|
||||||
|
"eslint": "^8",
|
||||||
|
"eslint-config-next": "14.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
gerbil-manager-nextjs/postcss.config.js
Normal file
6
gerbil-manager-nextjs/postcss.config.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
}
|
||||||
1
gerbil-manager-nextjs/public/next.svg
Normal file
1
gerbil-manager-nextjs/public/next.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
1
gerbil-manager-nextjs/public/vercel.svg
Normal file
1
gerbil-manager-nextjs/public/vercel.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 283 64"><path fill="black" d="M141 16c-11 0-19 7-19 18s9 18 20 18c7 0 13-3 16-7l-7-5c-2 3-6 4-9 4-5 0-9-3-10-7h28v-3c0-11-8-18-19-18zm-9 15c1-4 4-7 9-7s8 3 9 7h-18zm117-15c-11 0-19 7-19 18s9 18 20 18c6 0 12-3 16-7l-8-5c-2 3-5 4-8 4-5 0-9-3-11-7h28l1-3c0-11-8-18-19-18zm-10 15c2-4 5-7 10-7s8 3 9 7h-19zm-39 3c0 6 4 10 10 10 4 0 7-2 9-5l8 5c-3 5-9 8-17 8-11 0-19-7-19-18s8-18 19-18c8 0 14 3 17 8l-8 5c-2-3-5-5-9-5-6 0-10 4-10 10zm83-29v46h-9V5h9zM37 0l37 64H0L37 0zm92 5-27 48L74 5h10l18 30 17-30h10zm59 12v10l-3-1c-6 0-10 4-10 10v15h-9V17h9v9c0-5 6-9 13-9z"/></svg>
|
||||||
|
After Width: | Height: | Size: 629 B |
BIN
gerbil-manager-nextjs/src/app/favicon.ico
Normal file
BIN
gerbil-manager-nextjs/src/app/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
27
gerbil-manager-nextjs/src/app/globals.css
Normal file
27
gerbil-manager-nextjs/src/app/globals.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--foreground-rgb: 0, 0, 0;
|
||||||
|
--background-start-rgb: 214, 219, 220;
|
||||||
|
--background-end-rgb: 255, 255, 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
--foreground-rgb: 255, 255, 255;
|
||||||
|
--background-start-rgb: 0, 0, 0;
|
||||||
|
--background-end-rgb: 0, 0, 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
color: rgb(var(--foreground-rgb));
|
||||||
|
background: linear-gradient(
|
||||||
|
to bottom,
|
||||||
|
transparent,
|
||||||
|
rgb(var(--background-end-rgb))
|
||||||
|
)
|
||||||
|
rgb(var(--background-start-rgb));
|
||||||
|
}
|
||||||
22
gerbil-manager-nextjs/src/app/layout.tsx
Normal file
22
gerbil-manager-nextjs/src/app/layout.tsx
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import type { Metadata } from 'next'
|
||||||
|
import { Inter } from 'next/font/google'
|
||||||
|
import './globals.css'
|
||||||
|
|
||||||
|
const inter = Inter({ subsets: ['latin'] })
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: 'Create Next App',
|
||||||
|
description: 'Generated by create next app',
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function RootLayout({
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<html lang="en">
|
||||||
|
<body className={inter.className}>{children}</body>
|
||||||
|
</html>
|
||||||
|
)
|
||||||
|
}
|
||||||
121
gerbil-manager-nextjs/src/app/page.tsx
Normal file
121
gerbil-manager-nextjs/src/app/page.tsx
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
import Image from 'next/image'
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
return (
|
||||||
|
<aside className="flex">
|
||||||
|
<div className="flex flex-col items-center w-16 h-screen py-8 space-y-8 bg-white dark:bg-gray-900 dark:border-gray-700">
|
||||||
|
<a href="#">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="#" className="p-1.5 text-gray-500 focus:outline-nones transition-colors duration-200 rounded-lg dark:text-gray-400 dark:hover:bg-gray-800 hover:bg-gray-100">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="w-6 h-6">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" d="M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" />
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="#" className="p-1.5 text-blue-500 transition-colors duration-200 bg-blue-100 rounded-lg dark:text-blue-400 dark:bg-gray-800">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="w-6 h-6">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" d="M15 19.128a9.38 9.38 0 002.625.372 9.337 9.337 0 004.121-.952 4.125 4.125 0 00-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 018.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0111.964-3.07M12 6.375a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zm8.25 2.25a2.625 2.625 0 11-5.25 0 2.625 2.625 0 015.25 0z" />
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="#" className="p-1.5 text-gray-500 focus:outline-nones transition-colors duration-200 rounded-lg dark:text-gray-400 dark:hover:bg-gray-800 hover:bg-gray-100">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="w-6 h-6">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" d="M10.5 6a7.5 7.5 0 107.5 7.5h-7.5V6z" />
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" d="M13.5 10.5H21A7.5 7.5 0 0013.5 3v7.5z" />
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="#" className="p-1.5 text-gray-500 focus:outline-nones transition-colors duration-200 rounded-lg dark:text-gray-400 dark:hover:bg-gray-800 hover:bg-gray-100">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="w-6 h-6">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" d="M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0" />
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="#" className="p-1.5 text-gray-500 focus:outline-nones transition-colors duration-200 rounded-lg dark:text-gray-400 dark:hover:bg-gray-800 hover:bg-gray-100">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="w-6 h-6">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z" />
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="h-screen py-8 overflow-y-auto bg-white border-l border-r sm:w-64 w-60 dark:bg-gray-900 dark:border-gray-700">
|
||||||
|
<h2 className="px-5 text-lg font-medium text-gray-800 dark:text-white">Accounts</h2>
|
||||||
|
|
||||||
|
<div className="mt-8 space-y-4">
|
||||||
|
<button className="flex items-center w-full px-5 py-2 transition-colors duration-200 dark:hover:bg-gray-800 gap-x-2 hover:bg-gray-100 focus:outline-none">
|
||||||
|
|
||||||
|
<div className="text-left rtl:text-right">
|
||||||
|
<h1 className="text-sm font-medium text-gray-700 capitalize dark:text-white">Mia John</h1>
|
||||||
|
|
||||||
|
<p className="text-xs text-gray-500 dark:text-gray-400">11.2 Followers</p>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button className="flex items-center w-full px-5 py-2 transition-colors duration-200 dark:hover:bg-gray-800 gap-x-2 hover:bg-gray-100 focus:outline-none">
|
||||||
|
|
||||||
|
<div className="text-left rtl:text-right">
|
||||||
|
<h1 className="text-sm font-medium text-gray-700 capitalize dark:text-white">arthur melo</h1>
|
||||||
|
|
||||||
|
<p className="text-xs text-gray-500 dark:text-gray-400">1.2 Followers</p>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button className="flex items-center w-full px-5 py-2 transition-colors duration-200 bg-gray-100 dark:bg-gray-800 gap-x-2 focus:outline-none">
|
||||||
|
<div className="relative">
|
||||||
|
<span className="h-2 w-2 rounded-full bg-emerald-500 absolute right-0.5 ring-1 ring-white bottom-0"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="text-left rtl:text-right">
|
||||||
|
<h1 className="text-sm font-medium text-gray-700 capitalize dark:text-white">Jane Doe</h1>
|
||||||
|
|
||||||
|
<p className="text-xs text-gray-500 dark:text-gray-400">15.6 Followers</p>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button className="flex items-center w-full px-5 py-2 transition-colors duration-200 dark:hover:bg-gray-800 gap-x-2 hover:bg-gray-100 focus:outline-none">
|
||||||
|
|
||||||
|
<div className="text-left rtl:text-right">
|
||||||
|
<h1 className="text-sm font-medium text-gray-700 capitalize dark:text-white">Amelia. Anderson</h1>
|
||||||
|
|
||||||
|
<p className="text-xs text-gray-500 dark:text-gray-400">32.9 Followers</p>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button className="flex items-center w-full px-5 py-2 transition-colors duration-200 dark:hover:bg-gray-800 gap-x-2 hover:bg-gray-100 focus:outline-none">
|
||||||
|
<div className="text-left rtl:text-right">
|
||||||
|
<h1 className="text-sm font-medium text-gray-700 capitalize dark:text-white">Joseph Gonzalez</h1>
|
||||||
|
|
||||||
|
<p className="text-xs text-gray-500 dark:text-gray-400">100.2 Followers</p>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button className="flex items-center w-full px-5 py-2 transition-colors duration-200 hover:bg-gray-100 dark:hover:bg-gray-800 gap-x-2 focus:outline-none">
|
||||||
|
<div className="relative">
|
||||||
|
<span className="h-2 w-2 rounded-full bg-emerald-500 absolute right-0.5 ring-1 ring-white bottom-0"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="text-left rtl:text-right">
|
||||||
|
<h1 className="text-sm font-medium text-gray-700 capitalize dark:text-white">Olivia Wathan</h1>
|
||||||
|
|
||||||
|
<p className="text-xs text-gray-500 dark:text-gray-400">8.6 Followers</p>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button className="flex items-center w-full px-5 py-2 transition-colors duration-200 hover:bg-gray-100 dark:hover:bg-gray-800 gap-x-2 focus:outline-none">
|
||||||
|
<div className="relative">
|
||||||
|
<span className="h-2 w-2 rounded-full bg-emerald-500 absolute right-0.5 ring-1 ring-white bottom-0"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="text-left rtl:text-right">
|
||||||
|
<h1 className="text-sm font-medium text-gray-700 capitalize dark:text-white">Junior REIS</h1>
|
||||||
|
|
||||||
|
<p className="text-xs text-gray-500 dark:text-gray-400">56.6 Followers</p>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
)
|
||||||
|
}
|
||||||
20
gerbil-manager-nextjs/tailwind.config.ts
Normal file
20
gerbil-manager-nextjs/tailwind.config.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import type { Config } from 'tailwindcss'
|
||||||
|
|
||||||
|
const config: Config = {
|
||||||
|
content: [
|
||||||
|
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
|
||||||
|
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
|
||||||
|
'./src/app/**/*.{js,ts,jsx,tsx,mdx}',
|
||||||
|
],
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
backgroundImage: {
|
||||||
|
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
|
||||||
|
'gradient-conic':
|
||||||
|
'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
|
}
|
||||||
|
export default config
|
||||||
27
gerbil-manager-nextjs/tsconfig.json
Normal file
27
gerbil-manager-nextjs/tsconfig.json
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es5",
|
||||||
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"incremental": true,
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "next"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user