Compare commits
9 Commits
0b82942569
...
f633708b57
| Author | SHA1 | Date | |
|---|---|---|---|
| f633708b57 | |||
| 59eb99ab23 | |||
| 540b38eada | |||
| 7a6fe07d04 | |||
| 4b142d4e63 | |||
| 2b4e2f84a7 | |||
| 9c39e97126 | |||
| 3ddce62f54 | |||
| 1f443b2734 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
.idea
|
||||
bin/
|
||||
debug/
|
||||
obj/
|
||||
@@ -7,49 +7,63 @@
|
||||
@inherits ModuleBase
|
||||
@inject IBlackBoardService BlackBoardService
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IReportingHandler ReportingHandler
|
||||
@inject IStringLocalizer<Edit> Localizer
|
||||
@inject IReportUI ReportingComponent
|
||||
|
||||
<form @ref="form" class="@(validated ? " was-validated" : "needs-validation" )" novalidate>
|
||||
<form @ref="form" class="@(validated ? " was-validated" : "needs-validation")" novalidate>
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="name" HelpText="Enter a name" ResourceKey="Name">Name: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="name" class="form-control" @bind="@_name" required />
|
||||
<input id="name" class="form-control" @bind="@_blackBoard.Name" required/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="image" HelpText="Enter a description" ResourceKey="Description">Beschreibung: </Label>
|
||||
<div class="col-sm-9">
|
||||
<FileManager AnonymizeUploadFilenames="true" id="image" UploadMultiple="false" ShowSuccess="true" FileId="@_blackBoard.ImageID" OnSelectFile="@OnFileSelected"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="" For="description" HelpText="Enter a description" ResourceKey="Description">Beschreibung: </Label>
|
||||
<RichTextEditor @ref="RichTextEditorHtml" Content="@_blackBoard.Description" id="description" Placeholder="Enter a description: "/>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-success" @onclick="Save">@Localizer["Save"]</button>
|
||||
<button type="button" class="btn btn-danger" @onclick="Report">@Localizer["Report"]</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
|
||||
<br /><br />
|
||||
|
||||
@if (ReportingComponent != null)
|
||||
{
|
||||
<DynamicComponent Type="@ReportingComponent.ReportType" Parameters="@_parameters"/>
|
||||
}
|
||||
|
||||
<br/><br/>
|
||||
@if (PageState.Action == "Edit")
|
||||
{
|
||||
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
|
||||
<AuditInfo CreatedBy="@_blackBoard.CreatedBy" CreatedOn="@_blackBoard.CreatedOn" ModifiedBy="@_blackBoard.ModifiedBy" ModifiedOn="@_blackBoard.ModifiedOn"></AuditInfo>
|
||||
}
|
||||
</form>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
|
||||
|
||||
public override string RenderMode => RenderModes.Interactive;
|
||||
|
||||
public override string Actions => "Add,Edit";
|
||||
|
||||
public override string Title => "Manage BlackBoard";
|
||||
|
||||
public override List<Resource> Resources => new List<Resource>()
|
||||
{
|
||||
new Stylesheet("_content/SZUAbsolventenverein.Module.BlackBoard/Module.css")
|
||||
};
|
||||
public override List<Resource> Resources => [new Stylesheet("_content/SZUAbsolventenverein.Module.BlackBoard/Module.css")];
|
||||
|
||||
private RichTextEditor RichTextEditorHtml;
|
||||
private ElementReference form;
|
||||
private bool validated = false;
|
||||
private bool validated;
|
||||
|
||||
private int _id;
|
||||
private string _name;
|
||||
private string _createdby;
|
||||
private DateTime _createdon;
|
||||
private string _modifiedby;
|
||||
private DateTime _modifiedon;
|
||||
|
||||
// TODO
|
||||
private BlackBoard _blackBoard = new BlackBoard();
|
||||
private Dictionary<string, object> _parameters = new Dictionary<string, object>();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
@@ -58,14 +72,10 @@
|
||||
if (PageState.Action == "Edit")
|
||||
{
|
||||
_id = Int32.Parse(PageState.QueryString["id"]);
|
||||
BlackBoard BlackBoard = await BlackBoardService.GetBlackBoardAsync(_id, ModuleState.ModuleId);
|
||||
if (BlackBoard != null)
|
||||
_blackBoard = await BlackBoardService.GetBlackBoardAsync(_id, ModuleState.ModuleId);
|
||||
if (_blackBoard != null)
|
||||
{
|
||||
_name = BlackBoard.Name;
|
||||
_createdby = BlackBoard.CreatedBy;
|
||||
_createdon = BlackBoard.CreatedOn;
|
||||
_modifiedby = BlackBoard.ModifiedBy;
|
||||
_modifiedon = BlackBoard.ModifiedOn;
|
||||
_parameters = ReportingComponent.ConstructParameterList(_blackBoard, RenderModeBoundary);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,6 +86,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
private Task OnFileSelected(int fileId)
|
||||
{
|
||||
Console.WriteLine("File Selected: " + fileId);
|
||||
_blackBoard.ImageID = fileId;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task Save()
|
||||
{
|
||||
try
|
||||
@@ -84,21 +101,19 @@
|
||||
var interop = new Oqtane.UI.Interop(JSRuntime);
|
||||
if (await interop.FormValid(form))
|
||||
{
|
||||
_blackBoard.Description = await RichTextEditorHtml.GetHtml();
|
||||
if (PageState.Action == "Add")
|
||||
{
|
||||
BlackBoard BlackBoard = new BlackBoard();
|
||||
BlackBoard.ModuleId = ModuleState.ModuleId;
|
||||
BlackBoard.Name = _name;
|
||||
BlackBoard = await BlackBoardService.AddBlackBoardAsync(BlackBoard);
|
||||
await logger.LogInformation("BlackBoard Added {BlackBoard}", BlackBoard);
|
||||
_blackBoard.ModuleId = ModuleState.ModuleId;
|
||||
_blackBoard = await BlackBoardService.AddBlackBoardAsync(_blackBoard);
|
||||
await logger.LogInformation("BlackBoard Added {BlackBoard}", _blackBoard);
|
||||
}
|
||||
else
|
||||
{
|
||||
BlackBoard BlackBoard = await BlackBoardService.GetBlackBoardAsync(_id, ModuleState.ModuleId);
|
||||
BlackBoard.Name = _name;
|
||||
await BlackBoardService.UpdateBlackBoardAsync(BlackBoard);
|
||||
await logger.LogInformation("BlackBoard Updated {BlackBoard}", BlackBoard);
|
||||
await BlackBoardService.UpdateBlackBoardAsync(_blackBoard);
|
||||
await logger.LogInformation("BlackBoard Updated {BlackBoard}", _blackBoard);
|
||||
}
|
||||
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
else
|
||||
@@ -112,19 +127,5 @@
|
||||
AddModuleMessage(Localizer["Message.SaveError"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Report()
|
||||
{
|
||||
try
|
||||
{
|
||||
BlackBoard BlackBoard = await BlackBoardService.GetBlackBoardAsync(_id, ModuleState.ModuleId);
|
||||
BlackBoard.Name = _name;
|
||||
ReportingHandler.Report(BlackBoard, "Reported by user");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Reporting BlackBoard {BlackBoardId} {Error}", _id, ex.Message);
|
||||
AddModuleMessage(Localizer["Message.ReportError"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,76 +4,100 @@
|
||||
@namespace SZUAbsolventenverein.Module.BlackBoard
|
||||
@inherits ModuleBase
|
||||
@inject IBlackBoardService BlackBoardService
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IStringLocalizer<Index> Localizer
|
||||
|
||||
@if (_BlackBoards == null)
|
||||
@if (_blackBoards == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
<p>
|
||||
<em>Loading...</em>
|
||||
</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<ActionLink Action="Add" Security="SecurityAccessLevel.Edit" Text="Add BlackBoard" ResourceKey="Add" />
|
||||
<br />
|
||||
<br />
|
||||
@if (@_BlackBoards.Count != 0)
|
||||
{
|
||||
<Pager Items="@_BlackBoards">
|
||||
<Header>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th>@Localizer["Name"]</th>
|
||||
</Header>
|
||||
<Row>
|
||||
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.BlackBoardId.ToString())" ResourceKey="Edit" /></td>
|
||||
<td><ActionDialog Header="Delete BlackBoard" Message="Are You Sure You Wish To Delete This BlackBoard?" Action="Delete" Security="SecurityAccessLevel.Edit" Class="btn btn-danger" OnClick="@(async () => await Delete(context))" ResourceKey="Delete" Id="@context.BlackBoardId.ToString()" /></td>
|
||||
<td>@context.Name</td>
|
||||
</Row>
|
||||
</Pager>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p>@Localizer["Message.DisplayNone"]</p>
|
||||
}
|
||||
<ActionLink Action="Add" Security="SecurityAccessLevel.Edit" Text="Add BlackBoard" ResourceKey="Add"/>
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
@if (_blackBoards.Count != 0)
|
||||
{
|
||||
<div class="bb-card-grid">
|
||||
@foreach (var item in _blackBoards)
|
||||
{
|
||||
<div class="bb-card">
|
||||
@if (item.ImageID > 0)
|
||||
{
|
||||
<img class="bb-card-img" src="@ImageUrl(item.ImageID, 600, 400)" alt="@item.Name"/>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="bb-card-img-placeholder">
|
||||
<span>📋</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="bb-card-body">
|
||||
<h5>@item.Name</h5>
|
||||
@if (!string.IsNullOrWhiteSpace(item.Description))
|
||||
{
|
||||
<div class="bb-card-desc">@((MarkupString)item.Description)</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="bb-card-meta">
|
||||
<AuditInfo CreatedBy="@item.CreatedBy" CreatedOn="@item.CreatedOn" ModifiedBy="@item.ModifiedBy" ModifiedOn="@item.ModifiedOn"/>
|
||||
</div>
|
||||
|
||||
<div class="bb-card-footer">
|
||||
<ActionLink Action="Edit" Parameters="@("id=" + item.BlackBoardId.ToString())" ResourceKey="Edit"/>
|
||||
<ActionDialog Header="Delete BlackBoard" Message="Are You Sure You Wish To Delete This BlackBoard?" Action="Delete" Security="SecurityAccessLevel.Edit" Class="btn btn-danger" ConfirmClass="absolute" OnClick="@(async () => await Delete(item))" ResourceKey="Delete" Id="@item.BlackBoardId.ToString()"/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p>@Localizer["Message.DisplayNone"]</p>
|
||||
}
|
||||
}
|
||||
|
||||
@code {
|
||||
public override string RenderMode => RenderModes.Static;
|
||||
public override string RenderMode => RenderModes.Static;
|
||||
|
||||
public override List<Resource> Resources => new List<Resource>()
|
||||
public override List<Resource> Resources =>
|
||||
[
|
||||
new Stylesheet("_content/SZUAbsolventenverein.Module.BlackBoard/Module.css"),
|
||||
new Script("_content/SZUAbsolventenverein.Module.BlackBoard/Module.js")
|
||||
];
|
||||
|
||||
List<BlackBoard> _blackBoards;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
new Stylesheet("_content/SZUAbsolventenverein.Module.BlackBoard/Module.css"),
|
||||
new Script("_content/SZUAbsolventenverein.Module.BlackBoard/Module.js")
|
||||
};
|
||||
|
||||
List<BlackBoard> _BlackBoards;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
_BlackBoards = await BlackBoardService.GetBlackBoardsAsync(ModuleState.ModuleId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading BlackBoard {Error}", ex.Message);
|
||||
AddModuleMessage(Localizer["Message.LoadError"], MessageType.Error);
|
||||
}
|
||||
_blackBoards = await BlackBoardService.GetBlackBoardsAsync(ModuleState.ModuleId);
|
||||
}
|
||||
|
||||
private async Task Delete(BlackBoard BlackBoard)
|
||||
catch (Exception ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
await BlackBoardService.DeleteBlackBoardAsync(BlackBoard.BlackBoardId, ModuleState.ModuleId);
|
||||
await logger.LogInformation("BlackBoard Deleted {BlackBoard}", BlackBoard);
|
||||
_BlackBoards = await BlackBoardService.GetBlackBoardsAsync(ModuleState.ModuleId);
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Deleting BlackBoard {BlackBoard} {Error}", BlackBoard, ex.Message);
|
||||
AddModuleMessage(Localizer["Message.DeleteError"], MessageType.Error);
|
||||
}
|
||||
await logger.LogError(ex, "Error Loading BlackBoard {Error}", ex.Message);
|
||||
AddModuleMessage(Localizer["Message.LoadError"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Delete(BlackBoard blackBoard)
|
||||
{
|
||||
try
|
||||
{
|
||||
await BlackBoardService.DeleteBlackBoardAsync(blackBoard.BlackBoardId, ModuleState.ModuleId);
|
||||
await logger.LogInformation("BlackBoard Deleted {BlackBoard}", blackBoard);
|
||||
_blackBoards = await BlackBoardService.GetBlackBoardsAsync(ModuleState.ModuleId);
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Deleting BlackBoard {BlackBoard} {Error}", blackBoard, ex.Message);
|
||||
AddModuleMessage(Localizer["Message.DeleteError"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Interfaces" Version="0.0.0-12" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="10.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="10.0.1" />
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#!/bin/bash
|
||||
TargetFramework=$1
|
||||
ProjectName=$2
|
||||
|
||||
find . -name "*.nupkg" -delete
|
||||
"..\..\oqtane.framework\oqtane.package\FixProps.exe"
|
||||
"..\..\oqtane.framework\oqtane.package\nuget.exe" pack %ProjectName%.nuspec -Properties targetframework=%TargetFramework%;projectname=%ProjectName%
|
||||
dotnet run --project ../../fixProps/FixProps/FixProps.csproj
|
||||
dotnet pack $ProjectName.nuspec "/p:targetframework=${TargetFramework};projectname=${ProjectName}"
|
||||
cp -f "*.nupkg" "..\..\oqtane.framework\Oqtane.Server\Packages\"
|
||||
38
Server/Infrastructure/BlackBoardDigestJob.cs
Normal file
38
Server/Infrastructure/BlackBoardDigestJob.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Oqtane.Infrastructure;
|
||||
using Oqtane.Repository;
|
||||
|
||||
namespace SZUAbsolventenverein.Module.BlackBoard.Infrastructure
|
||||
{
|
||||
public class BlackBoardDigestJob : HostedServiceBase
|
||||
{
|
||||
// JobType = "SZUAbsolventenverein.Module.BlackBoard.Infrastructure, SZUAbsolventenverein.Module.BlackBoard.Server.Oqtane"
|
||||
|
||||
public BlackBoardDigestJob(IServiceScopeFactory serviceScopeFactory) : base(serviceScopeFactory)
|
||||
{
|
||||
Name = "BlackBoardDigestJob";
|
||||
Frequency = "m";
|
||||
Interval = 1;
|
||||
IsEnabled = false;
|
||||
}
|
||||
|
||||
public override Task<string> ExecuteJobAsync(IServiceProvider provider)
|
||||
{
|
||||
StringBuilder log = new StringBuilder();
|
||||
|
||||
var sites = provider.GetRequiredService<ISiteRepository>();
|
||||
|
||||
foreach (var site in sites.GetSites())
|
||||
{
|
||||
log.AppendLine(site.Name);
|
||||
}
|
||||
|
||||
return Task.FromResult(log.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
30
Server/Migrations/01000001_AddDescriptionColumn.cs
Normal file
30
Server/Migrations/01000001_AddDescriptionColumn.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Oqtane.Databases.Interfaces;
|
||||
using Oqtane.Migrations;
|
||||
using SZUAbsolventenverein.Module.BlackBoard.Migrations.EntityBuilders;
|
||||
using SZUAbsolventenverein.Module.BlackBoard.Repository;
|
||||
|
||||
namespace SZUAbsolventenverein.Module.BlackBoard.Migrations
|
||||
{
|
||||
[DbContext(typeof(BlackBoardContext))]
|
||||
[Migration("SZUAbsolventenverein.Module.BlackBoard.01.00.00.01")]
|
||||
public class AddDescriptionColumn : MultiDatabaseMigration
|
||||
{
|
||||
public AddDescriptionColumn(IDatabase database) : base(database)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
var entityBuilder = new BlackBoardEntityBuilder(migrationBuilder, ActiveDatabase);
|
||||
entityBuilder.AddStringColumn("Description", 1000, true, false);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
var entityBuilder = new BlackBoardEntityBuilder(migrationBuilder, ActiveDatabase);
|
||||
entityBuilder.DropColumn("Description");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,12 +12,14 @@ namespace SZUAbsolventenverein.Module.BlackBoard.Migrations.EntityBuilders
|
||||
private const string _entityTableName = "SZUAbsolventenvereinBlackBoard";
|
||||
private readonly PrimaryKey<BlackBoardEntityBuilder> _primaryKey = new("PK_SZUAbsolventenvereinBlackBoard", x => x.BlackBoardId);
|
||||
private readonly ForeignKey<BlackBoardEntityBuilder> _moduleForeignKey = new("FK_SZUAbsolventenvereinBlackBoard_Module", x => x.ModuleId, "Module", "ModuleId", ReferentialAction.Cascade);
|
||||
private readonly ForeignKey<BlackBoardEntityBuilder> _fileForeignKey = new("FK_SZUAbsolventenvereinBlackBoard_File", x => x.ImageID, "File", "FileId", ReferentialAction.Cascade);
|
||||
|
||||
public BlackBoardEntityBuilder(MigrationBuilder migrationBuilder, IDatabase database) : base(migrationBuilder, database)
|
||||
{
|
||||
EntityTableName = _entityTableName;
|
||||
PrimaryKey = _primaryKey;
|
||||
ForeignKeys.Add(_moduleForeignKey);
|
||||
ForeignKeys.Add(_fileForeignKey);
|
||||
}
|
||||
|
||||
protected override BlackBoardEntityBuilder BuildTable(ColumnsBuilder table)
|
||||
@@ -25,6 +27,7 @@ namespace SZUAbsolventenverein.Module.BlackBoard.Migrations.EntityBuilders
|
||||
BlackBoardId = AddAutoIncrementColumn(table,"BlackBoardId");
|
||||
ModuleId = AddIntegerColumn(table,"ModuleId");
|
||||
Name = AddMaxStringColumn(table,"Name");
|
||||
ImageID = AddIntegerColumn(table,"ImageID");
|
||||
AddAuditableColumns(table);
|
||||
return this;
|
||||
}
|
||||
@@ -32,5 +35,6 @@ namespace SZUAbsolventenverein.Module.BlackBoard.Migrations.EntityBuilders
|
||||
public OperationBuilder<AddColumnOperation> BlackBoardId { get; set; }
|
||||
public OperationBuilder<AddColumnOperation> ModuleId { get; set; }
|
||||
public OperationBuilder<AddColumnOperation> Name { get; set; }
|
||||
public OperationBuilder<AddColumnOperation> ImageID { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1,79 @@
|
||||
/* Module Custom Styles */
|
||||
/* Module Custom Styles */
|
||||
|
||||
/* ── Blackboard Card Grid ── */
|
||||
.bb-card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.bb-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 0.75rem;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
transition:
|
||||
box-shadow 0.2s ease,
|
||||
transform 0.2s ease;
|
||||
}
|
||||
|
||||
.bb-card:hover {
|
||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.bb-card-img {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.bb-card-img-placeholder {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(135deg, #e9ecef 0%, #dee2e6 100%);
|
||||
color: #adb5bd;
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.bb-card-body {
|
||||
padding: 1.25rem;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.bb-card-body h5 {
|
||||
margin: 0 0 0.5rem;
|
||||
font-size: 1.15rem;
|
||||
font-weight: 600;
|
||||
color: #212529;
|
||||
}
|
||||
|
||||
.bb-card-desc {
|
||||
font-size: 0.9rem;
|
||||
color: #495057;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.bb-card-meta {
|
||||
padding: 0 1.25rem 0.75rem;
|
||||
font-size: 0.8rem;
|
||||
color: #6c757d;
|
||||
}
|
||||
|
||||
.bb-card-footer {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
padding: 0.75rem 1.25rem;
|
||||
border-top: 1px solid #e9ecef;
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ namespace SZUAbsolventenverein.Module.BlackBoard.Models
|
||||
public int BlackBoardId { get; set; }
|
||||
public int ModuleId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public int ImageID { get; set; }
|
||||
public string Description { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string ModuleName => "BlackBoard";
|
||||
@@ -19,5 +21,7 @@ namespace SZUAbsolventenverein.Module.BlackBoard.Models
|
||||
public int ModuleID => ModuleId;
|
||||
[NotMapped]
|
||||
public int EntityID => BlackBoardId;
|
||||
|
||||
[NotMapped] public string UserName => CreatedBy;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,12 +13,10 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||
<PackageReference Include="Interfaces" Version="0.0.0-12" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Interfaces">
|
||||
<HintPath>..\..\interfaces\Interfaces\bin\Debug\net10.0\Interfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Oqtane.Shared"><HintPath>..\..\oqtane.framework\Oqtane.Server\bin\Debug\net10.0\Oqtane.Shared.dll</HintPath></Reference>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user