Intranet SocialPost

This commit is contained in:
Sedat ÖZTÜRK 2025-10-28 13:57:32 +03:00
parent 9d50954cc4
commit 5be636531a
28 changed files with 2454 additions and 463 deletions

View file

@ -6679,6 +6679,12 @@
"tr": "Ziyaretçiler",
"en": "Visitors"
},
{
"resourceName": "Platform",
"key": "App.Intranet.SocialPost",
"tr": "Sosyal Paylaşımlar",
"en": "Social Posts"
},
{
"resourceName": "Platform",
"key": "App.Definitions.Information",

View file

@ -41067,7 +41067,7 @@ public class ListFormSeeder : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.String,
FieldName = "CompanyName",
Width = 200,
Width = 300,
ListOrderNo = 3,
Visible = true,
IsActive = true,
@ -41101,7 +41101,7 @@ public class ListFormSeeder : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.String,
FieldName = "Email",
Width = 100,
Width = 150,
ListOrderNo = 4,
Visible = true,
IsActive = true,
@ -41240,7 +41240,7 @@ public class ListFormSeeder : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.DateTime,
FieldName = "CheckIn",
Width = 100,
Width = 150,
ListOrderNo = 8,
Visible = true,
IsActive = true,
@ -41271,7 +41271,7 @@ public class ListFormSeeder : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.DateTime,
FieldName = "CheckOut",
Width = 100,
Width = 150,
ListOrderNo = 9,
Visible = true,
IsActive = true,
@ -43017,6 +43017,356 @@ public class ListFormSeeder : IDataSeedContributor, ITransientDependency
}
#endregion
#region Social Post
if (!await _listFormRepository.AnyAsync(a => a.ListFormCode == ListFormCodes.Lists.SocialPost))
{
var listFormSocialPost = await _listFormRepository.InsertAsync(
new ListForm()
{
ListFormType = ListFormTypeEnum.List,
IsSubForm = true,
LayoutJson = JsonSerializer.Serialize(new LayoutDto()
{
Grid = true,
Card = true,
Pivot = true,
Chart = true,
DefaultLayout = "grid",
CardLayoutColumn = 3
}),
CultureName = LanguageCodes.En,
ListFormCode = ListFormCodes.Lists.SocialPost,
Name = AppCodes.Intranet.SocialPost,
Title = AppCodes.Intranet.SocialPost,
DataSourceCode = SeedConsts.DataSources.DefaultCode,
IsTenant = true,
IsBranch = false,
IsOrganizationUnit = false,
Description = AppCodes.Intranet.SocialPost,
SelectCommandType = SelectCommandTypeEnum.Table,
SelectCommand = TableNameResolver.GetFullTableName(nameof(TableNameEnum.SocialPost)),
KeyFieldName = "Id",
KeyFieldDbSourceType = DbType.Guid,
DefaultFilter = "\"IsDeleted\" = 'false'",
SortMode = GridOptions.SortModeSingle,
FilterRowJson = JsonSerializer.Serialize(new GridFilterRowDto { Visible = true }),
HeaderFilterJson = JsonSerializer.Serialize(new { Visible = true }),
SearchPanelJson = JsonSerializer.Serialize(new { Visible = true }),
GroupPanelJson = JsonSerializer.Serialize(new { Visible = true }),
SelectionJson = JsonSerializer.Serialize(new SelectionDto
{
Mode = GridOptions.SelectionModeSingle,
AllowSelectAll = false
}),
ColumnOptionJson = JsonSerializer.Serialize(new
{
ColumnFixingEnabled = true,
ColumnAutoWidth = true,
ColumnChooserEnabled = true,
AllowColumnResizing = true,
AllowColumnReordering = true,
ColumnResizingMode = "widget",
}),
PermissionJson = JsonSerializer.Serialize(new PermissionCrudDto
{
C = AppCodes.Intranet.SocialPost + ".Create",
R = AppCodes.Intranet.SocialPost,
U = AppCodes.Intranet.SocialPost + ".Update",
D = AppCodes.Intranet.SocialPost + ".Delete",
E = AppCodes.Intranet.SocialPost + ".Export",
I = AppCodes.Intranet.SocialPost + ".Import",
A = AppCodes.Intranet.SocialPost + ".Activity",
}),
DeleteCommand = $"UPDATE \"{TableNameResolver.GetFullTableName(nameof(TableNameEnum.SocialPost))}\" SET \"DeleterId\"=@DeleterId, \"DeletionTime\"=CURRENT_TIMESTAMP, \"IsDeleted\"='true' WHERE \"Id\"=@Id",
DeleteFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] {
new() {
FieldName = "DeleterId",
FieldDbType = DbType.Guid,
Value = "@USERID",
CustomValueType = FieldCustomValueTypeEnum.CustomKey },
new() {
FieldName = "Id",
FieldDbType = DbType.Guid,
Value = "@ID",
CustomValueType = FieldCustomValueTypeEnum.CustomKey }
}),
PagerOptionJson = JsonSerializer.Serialize(new GridPagerOptionDto
{
Visible = true,
AllowedPageSizes = "10,20,50,100",
ShowPageSizeSelector = true,
ShowNavigationButtons = true,
ShowInfo = false,
InfoText = "Page {0} of {1} ({2} items)",
DisplayMode = GridColumnOptions.PagerDisplayModeAdaptive,
ScrollingMode = GridColumnOptions.ScrollingModeStandard,
LoadPanelEnabled = "auto",
LoadPanelText = "Loading..."
}),
EditingOptionJson = JsonSerializer.Serialize(new GridEditingDto
{
Popup = new GridEditingPopupDto()
{
Title = "Social Post Form",
Width = 500,
Height = 400
},
AllowDeleting = true,
AllowAdding = true,
AllowUpdating = true,
SendOnlyChangedFormValuesUpdate = false,
}),
InsertFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] {
new() {
FieldName = "CreationTime",
FieldDbType = DbType.DateTime,
Value = "@NOW",
CustomValueType = FieldCustomValueTypeEnum.CustomKey },
new() {
FieldName = "CreatorId",
FieldDbType = DbType.Guid,
Value = "@USERID",
CustomValueType = FieldCustomValueTypeEnum.CustomKey },
new() {
FieldName = "IsDeleted",
FieldDbType = DbType.Boolean,
Value = "false",
CustomValueType = FieldCustomValueTypeEnum.Value }
}),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>()
{
new() {
Order=1, ColCount=1, ColSpan=2, ItemType="group", Items =
[
new EditingFormItemDto { Order = 1, DataField = "EmployeeId", IsRequired = true, EditorType2 = EditorTypes.dxSelectBox },
new EditingFormItemDto { Order = 2, DataField = "Content", IsRequired = true, EditorType2 = EditorTypes.dxTextArea },
new EditingFormItemDto { Order = 3, DataField = "LikeCount", IsRequired = true, EditorType2 = EditorTypes.dxNumberBox },
new EditingFormItemDto { Order = 4, DataField = "IsLiked", IsRequired = true, EditorType2 = EditorTypes.dxCheckBox },
new EditingFormItemDto { Order = 5, DataField = "IsOwnPost", IsRequired = true, EditorType2 = EditorTypes.dxCheckBox }
]
}
}),
CommandColumnJson = JsonSerializer.Serialize(new CommandColumnDto[] {
new() {
Hint = "Comments",
Text ="Comments",
UrlTarget="_blank",
AuthName = AppCodes.Hr.SurveyResponse + ".Update",
Url="/admin/list/list-employees/@Id"
},
}),
}
);
#region Social Post Fields
await _listFormFieldRepository.InsertManyAsync([
new() {
ListFormCode = listFormSocialPost.ListFormCode,
RoleId = null,
UserId = null,
CultureName = LanguageCodes.En,
SourceDbType = DbType.Guid,
FieldName = "Id",
Width = 100,
ListOrderNo = 1,
Visible = false,
IsActive = true,
IsDeleted = false,
SortIndex = 0,
ValidationRuleJson = JsonSerializer.Serialize(new ValidationRuleDto[] {
new ValidationRuleDto() { Type = Enum.GetName(UiColumnValidationRuleTypeEnum.required) }
}),
ColumnCustomizationJson = JsonSerializer.Serialize(new ColumnCustomizationDto
{
AllowReordering = true,
}),
PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto
{
C = AppCodes.Intranet.SocialPost + ".Create",
R = AppCodes.Intranet.SocialPost,
U = AppCodes.Intranet.SocialPost + ".Update",
E = true,
I = true,
Deny = false
}),
PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto
{
IsPivot = true
})
},
new() {
ListFormCode = listFormSocialPost.ListFormCode,
RoleId = null,
UserId = null,
CultureName = LanguageCodes.En,
SourceDbType = DbType.Guid,
FieldName = "EmployeeId",
Width = 100,
ListOrderNo = 2,
Visible = true,
IsActive = true,
IsDeleted = false,
AllowSearch = true,
LookupJson = JsonSerializer.Serialize(new LookupDto
{
DataSourceType = UiLookupDataSourceTypeEnum.Query,
DisplayExpr = "name",
ValueExpr = "key",
LookupQuery = LookUpQueryValues.EmployeeValues
}),
ValidationRuleJson = JsonSerializer.Serialize(new ValidationRuleDto[] {
new ValidationRuleDto() { Type = Enum.GetName(UiColumnValidationRuleTypeEnum.required) }
}),
ColumnCustomizationJson = JsonSerializer.Serialize(new ColumnCustomizationDto
{
AllowReordering = true,
}),
PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto
{
C = AppCodes.Intranet.SocialPost + ".Create",
R = AppCodes.Intranet.SocialPost,
U = AppCodes.Intranet.SocialPost + ".Update",
E = true,
I = true,
Deny = false
}),
PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto
{
IsPivot = true
})
},
new() {
ListFormCode = listFormSocialPost.ListFormCode,
RoleId = null,
UserId = null,
CultureName = LanguageCodes.En,
SourceDbType = DbType.String,
FieldName = "Content",
Width = 800,
ListOrderNo = 3,
Visible = true,
IsActive = true,
IsDeleted = false,
AllowSearch = true,
ValidationRuleJson = JsonSerializer.Serialize(new ValidationRuleDto[] {
new ValidationRuleDto() { Type = Enum.GetName(UiColumnValidationRuleTypeEnum.required) }
}),
ColumnCustomizationJson = JsonSerializer.Serialize(new ColumnCustomizationDto
{
AllowReordering = true,
}),
PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto
{
C = AppCodes.Intranet.SocialPost + ".Create",
R = AppCodes.Intranet.SocialPost,
U = AppCodes.Intranet.SocialPost + ".Update",
E = true,
I = true,
Deny = false
}),
PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto
{
IsPivot = true
})
},
new() {
ListFormCode = listFormSocialPost.ListFormCode,
RoleId = null,
UserId = null,
CultureName = LanguageCodes.En,
SourceDbType = DbType.Int32,
FieldName = "LikeCount",
Width = 100,
ListOrderNo = 4,
Visible = true,
IsActive = true,
IsDeleted = false,
AllowSearch = true,
ColumnCustomizationJson = JsonSerializer.Serialize(new ColumnCustomizationDto
{
AllowReordering = true,
}),
PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto
{
C = AppCodes.Intranet.SocialPost + ".Create",
R = AppCodes.Intranet.SocialPost,
U = AppCodes.Intranet.SocialPost + ".Update",
E = true,
I = true,
Deny = false
}),
PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto
{
IsPivot = true
})
},
new() {
ListFormCode = listFormSocialPost.ListFormCode,
RoleId = null,
UserId = null,
CultureName = LanguageCodes.En,
SourceDbType = DbType.Boolean,
FieldName = "IsLiked",
Width = 100,
ListOrderNo = 5,
Visible = true,
IsActive = true,
IsDeleted = false,
AllowSearch = true,
ColumnCustomizationJson = JsonSerializer.Serialize(new ColumnCustomizationDto
{
AllowReordering = true,
}),
PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto
{
C = AppCodes.Intranet.SocialPost + ".Create",
R = AppCodes.Intranet.SocialPost,
U = AppCodes.Intranet.SocialPost + ".Update",
E = true,
I = true,
Deny = false
}),
PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto
{
IsPivot = true
})
},
new() {
ListFormCode = listFormSocialPost.ListFormCode,
RoleId = null,
UserId = null,
CultureName = LanguageCodes.En,
SourceDbType = DbType.Boolean,
FieldName = "IsOwnPost",
Width = 100,
ListOrderNo = 6,
Visible = true,
IsActive = true,
IsDeleted = false,
AllowSearch = true,
ColumnCustomizationJson = JsonSerializer.Serialize(new ColumnCustomizationDto
{
AllowReordering = true,
}),
PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto
{
C = AppCodes.Intranet.SocialPost + ".Create",
R = AppCodes.Intranet.SocialPost,
U = AppCodes.Intranet.SocialPost + ".Update",
E = true,
I = true,
Deny = false
}),
PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto
{
IsPivot = true
})
},
]);
#endregion
}
#endregion
#endregion
}
}

View file

@ -2141,6 +2141,16 @@
"RequiredPermissionName": "App.Intranet.Visitor",
"IsDisabled": false
},
{
"ParentCode": "App.Intranet",
"Code": "App.Intranet.SocialPost",
"DisplayName": "App.Intranet.SocialPost",
"Order": 7,
"Url": "/admin/list/list-socialpost",
"Icon": "FcShare",
"RequiredPermissionName": "App.Intranet.SocialPost",
"IsDisabled": false
},
{
"ParentCode": null,
"Code": "App.Participant",

View file

@ -8995,6 +8995,80 @@
"MultiTenancySide": 3,
"MenuGroup": "Kurs"
},
{
"GroupName": "App.Intranet",
"Name": "App.Intranet.SocialPost",
"ParentName": null,
"DisplayName": "App.Intranet.SocialPost",
"IsEnabled": true,
"MultiTenancySide": 3,
"MenuGroup": "Kurs"
},
{
"GroupName": "App.Intranet",
"Name": "App.Intranet.SocialPost.Create",
"ParentName": "App.Intranet.SocialPost",
"DisplayName": "Create",
"IsEnabled": true,
"MultiTenancySide": 3,
"MenuGroup": "Kurs"
},
{
"GroupName": "App.Intranet",
"Name": "App.Intranet.SocialPost.Update",
"ParentName": "App.Intranet.SocialPost",
"DisplayName": "Update",
"IsEnabled": true,
"MultiTenancySide": 3,
"MenuGroup": "Kurs"
},
{
"GroupName": "App.Intranet",
"Name": "App.Intranet.SocialPost.Delete",
"ParentName": "App.Intranet.SocialPost",
"DisplayName": "Delete",
"IsEnabled": true,
"MultiTenancySide": 3,
"MenuGroup": "Kurs"
},
{
"GroupName": "App.Intranet",
"Name": "App.Intranet.SocialPost.Export",
"ParentName": "App.Intranet.SocialPost",
"DisplayName": "Export",
"IsEnabled": true,
"MultiTenancySide": 3,
"MenuGroup": "Kurs"
},
{
"GroupName": "App.Intranet",
"Name": "App.Intranet.SocialPost.Import",
"ParentName": "App.Intranet.SocialPost",
"DisplayName": "Import",
"IsEnabled": true,
"MultiTenancySide": 3,
"MenuGroup": "Kurs"
},
{
"GroupName": "App.Intranet",
"Name": "App.Intranet.SocialPost.Activity",
"ParentName": "App.Intranet.SocialPost",
"DisplayName": "Activity",
"IsEnabled": true,
"MultiTenancySide": 3,
"MenuGroup": "Kurs"
},
{
"GroupName": "App.Intranet",
"Name": "App.Intranet.SocialPost.Widget",
"ParentName": "App.Intranet.SocialPost",
"DisplayName": "Widget",
"IsEnabled": true,
"MultiTenancySide": 3,
"MenuGroup": "Kurs"
},
{
"GroupName": "App.Crm",
"Name": "App.Crm.Customer",

View file

@ -128,5 +128,11 @@ public enum TableNameEnum
SurveyQuestion,
SurveyQuestionOption,
SurveyResponse,
SurveyAnswer
SurveyAnswer,
SocialPost,
SocialLocation,
SocialMedia,
SocialPollOption,
SocialComment,
SocialLike
}

View file

@ -539,6 +539,7 @@ public static class PlatformConsts
public const string SurveyQuestion = "list-surveyquestion";
public const string SurveyQuestionOption = "list-surveyquestionoption";
public const string SurveyResponse = "list-surveyresponse";
public const string SocialPost = "list-socialpost";
}
}

View file

@ -148,6 +148,12 @@ public static class TableNameResolver
{ nameof(TableNameEnum.ShuttleRoute), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Intranet) },
{ nameof(TableNameEnum.Announcement), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Intranet) },
{ nameof(TableNameEnum.Visitor), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Intranet) },
{ nameof(TableNameEnum.SocialPost), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Intranet) },
{ nameof(TableNameEnum.SocialLocation), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Intranet) },
{ nameof(TableNameEnum.SocialMedia), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Intranet) },
{ nameof(TableNameEnum.SocialPollOption), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Intranet) },
{ nameof(TableNameEnum.SocialComment), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Intranet) },
{ nameof(TableNameEnum.SocialLike), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Intranet) },
// 🔹 ACCOUNTING
{ nameof(TableNameEnum.Bank), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Accounting) },

View file

@ -458,6 +458,7 @@ public static class SeedConsts
public const string ShuttleRoute = Default + ".ShuttleRoute";
public const string Announcement = Default + ".Announcement";
public const string Visitor = Default + ".Visitor";
public const string SocialPost = Default + ".SocialPost";
}
public static class Hr

View file

@ -5,95 +5,90 @@ using Volo.Abp.MultiTenancy;
namespace Kurs.Platform.Entities;
public class SocialLocation : FullAuditedEntity<Guid>, IMultiTenant
{
public Guid? TenantId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public double Lat { get; set; }
public double Lng { get; set; }
public string PlaceId { get; set; }
}
public class SocialPost : FullAuditedEntity<Guid>, IMultiTenant
{
public Guid? TenantId { get; set; }
public Guid AuthorId { get; set; }
public Employee Author { get; set; }
public Guid? EmployeeId { get; set; }
public Employee? Employee { get; set; }
public string Content { get; set; }
public Guid? LocationId { get; set; }
public SocialLocation Location { get; set; }
public Guid? MediaId { get; set; }
public SocialMedia Media { get; set; }
public int LikesCount { get; set; }
public int LikeCount { get; set; }
public bool IsLiked { get; set; }
public bool IsOwnPost { get; set; }
public ICollection<SocialLikeUser> LikeUsers { get; set; }
// Relations
public SocialLocation? Location { get; set; }
public SocialMedia? Media { get; set; }
public ICollection<SocialComment> Comments { get; set; }
public ICollection<SocialLike> Likes { get; set; }
}
public class SocialLikeUser : FullAuditedEntity<Guid>, IMultiTenant
public class SocialLocation : FullAuditedEntity<Guid>, IMultiTenant
{
public Guid? TenantId { get; set; }
public Guid PostId { get; set; }
public SocialPost Post { get; set; }
public Guid SocialPostId { get; set; }
public SocialPost SocialPost { get; set; }
public Guid UserId { get; set; }
public Employee User { get; set; }
}
public class SocialComment : FullAuditedEntity<Guid>, IMultiTenant
{
public Guid? TenantId { get; set; }
public Guid PostId { get; set; }
public SocialPost Post { get; set; }
public Guid AuthorId { get; set; }
public Employee Author { get; set; }
public string Content { get; set; }
public string Name { get; set; }
public string? Address { get; set; }
public double? Lat { get; set; }
public double? Lng { get; set; }
public string? PlaceId { get; set; }
}
public class SocialMedia : FullAuditedEntity<Guid>, IMultiTenant
{
public Guid? TenantId { get; set; }
public string Type { get; set; } // "image" | "video" | "poll"
public string Url { get; set; }
public string UrlsJson { get; set; } // Çoklu URLler JSON saklanabilir
public string FilePath { get; set; }
public Guid SocialPostId { get; set; }
public SocialPost SocialPost { get; set; }
public Guid? PollId { get; set; }
public SocialPoll Poll { get; set; }
}
public string Type { get; set; } // image | video | poll
public string[] Urls { get; set; }
public class SocialPoll : FullAuditedEntity<Guid>, IMultiTenant
{
public Guid? TenantId { get; set; }
// Poll fields
public string? PollQuestion { get; set; }
public int? PollTotalVotes { get; set; }
public DateTime? PollEndsAt { get; set; }
public string? PollUserVoteId { get; set; }
public string Question { get; set; }
public int TotalVotes { get; set; }
public DateTime EndsAt { get; set; }
public string UserVote { get; set; }
public ICollection<SocialPollOption> Options { get; set; }
public ICollection<SocialPollOption> PollOptions { get; set; }
}
public class SocialPollOption : FullAuditedEntity<Guid>, IMultiTenant
{
public Guid? TenantId { get; set; }
public Guid PollId { get; set; }
public SocialPoll Poll { get; set; }
public Guid SocialMediaId { get; set; }
public SocialMedia SocialMedia { get; set; }
public string Text { get; set; }
public int Votes { get; set; }
}
public class SocialComment : FullAuditedEntity<Guid>, IMultiTenant
{
public Guid? TenantId { get; set; }
public Guid SocialPostId { get; set; }
public SocialPost SocialPost { get; set; }
public Guid? EmployeeId { get; set; }
public Employee? Employee { get; set; }
public string Content { get; set; }
}
public class SocialLike : FullAuditedEntity<Guid>, IMultiTenant
{
public Guid? TenantId { get; set; }
public Guid SocialPostId { get; set; }
public SocialPost SocialPost { get; set; }
public Guid? EmployeeId { get; set; }
public Employee? Employee { get; set; }
}

View file

@ -91,14 +91,8 @@ public class PlatformDbContext :
public DbSet<ScheduleLesson> ScheduleLessons { get; set; }
public DbSet<ClassType> ClassTypes { get; set; }
public DbSet<Class> Classes { get; set; }
public DbSet<Event> Events { get; set; }
public DbSet<EventCategory> EventCategories { get; set; }
public DbSet<EventType> EventTypes { get; set; }
public DbSet<EventPhoto> EventPhotos { get; set; }
public DbSet<EventComment> EventComments { get; set; }
public DbSet<LessonPeriod> LessonPeriods { get; set; }
public DbSet<Lawyer> Lawyers { get; set; }
public DbSet<Meal> Meals { get; set; }
public DbSet<Disease> Diseases { get; set; }
public DbSet<Document> Documents { get; set; }
public DbSet<Interesting> InterestAreas { get; set; }
@ -179,10 +173,6 @@ public class PlatformDbContext :
public DbSet<Performans360> Performans360s { get; set; }
public DbSet<Training> Trainings { get; set; }
public DbSet<Certificate> Certificates { get; set; }
public DbSet<Reservation> Reservations { get; set; }
public DbSet<ShuttleRoute> ShuttleRoutes { get; set; }
public DbSet<Announcement> Announcements { get; set; }
public DbSet<Visitor> Visitors { get; set; }
public DbSet<Expense> ExpenseRequests { get; set; }
public DbSet<Survey> Surveys { get; set; }
public DbSet<SurveyQuestion> SurveyQuestions { get; set; }
@ -192,6 +182,26 @@ public class PlatformDbContext :
#endregion
#region Intranet
public DbSet<Event> Events { get; set; }
public DbSet<EventCategory> EventCategories { get; set; }
public DbSet<EventType> EventTypes { get; set; }
public DbSet<EventPhoto> EventPhotos { get; set; }
public DbSet<EventComment> EventComments { get; set; }
public DbSet<Meal> Meals { get; set; }
public DbSet<Reservation> Reservations { get; set; }
public DbSet<ShuttleRoute> ShuttleRoutes { get; set; }
public DbSet<Announcement> Announcements { get; set; }
public DbSet<Visitor> Visitors { get; set; }
public DbSet<SocialPost> SocialPosts { get; set; }
public DbSet<SocialLocation> SocialLocations { get; set; }
public DbSet<SocialMedia> SocialMedias { get; set; }
public DbSet<SocialPollOption> SocialPollOptions { get; set; }
public DbSet<SocialComment> SocialComments { get; set; }
public DbSet<SocialLike> SocialLikes { get; set; }
#endregion
public PlatformDbContext(DbContextOptions<PlatformDbContext> options)
: base(options)
{
@ -2105,5 +2115,84 @@ public class PlatformDbContext :
.HasForeignKey(x => x.QuestionId)
.OnDelete(DeleteBehavior.Restrict);
});
builder.Entity<SocialPost>(b =>
{
b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.SocialPost)), Prefix.DbSchema);
b.ConfigureByConvention();
b.Property(x => x.Content).IsRequired().HasMaxLength(4000);
b.Property(x => x.LikeCount).HasDefaultValue(0);
b.Property(x => x.IsOwnPost).HasDefaultValue(false);
b.Property(x => x.IsLiked).HasDefaultValue(false);
});
builder.Entity<SocialLocation>(b =>
{
b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.SocialLocation)), Prefix.DbSchema);
b.ConfigureByConvention();
b.Property(x => x.Name).IsRequired().HasMaxLength(256);
b.Property(x => x.Address).HasMaxLength(512);
b.Property(x => x.PlaceId).HasMaxLength(128);
b.HasOne(x => x.SocialPost)
.WithOne(p => p.Location)
.HasForeignKey<SocialLocation>(x => x.SocialPostId)
.OnDelete(DeleteBehavior.Cascade);
});
builder.Entity<SocialMedia>(b =>
{
b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.SocialMedia)), Prefix.DbSchema);
b.ConfigureByConvention();
b.Property(x => x.Type).IsRequired().HasMaxLength(64);
b.Property(x => x.Urls).HasMaxLength(2000);
b.HasOne(x => x.SocialPost)
.WithOne(p => p.Media)
.HasForeignKey<SocialMedia>(x => x.SocialPostId) // ✅ doğru entity
.OnDelete(DeleteBehavior.Cascade);
});
builder.Entity<SocialPollOption>(b =>
{
b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.SocialPollOption)), Prefix.DbSchema);
b.ConfigureByConvention();
b.Property(x => x.Text).IsRequired().HasMaxLength(512);
b.HasOne(x => x.SocialMedia)
.WithMany(x => x.PollOptions)
.HasForeignKey(x => x.SocialMediaId)
.OnDelete(DeleteBehavior.Cascade);
});
// 🔹 SocialComment
builder.Entity<SocialComment>(b =>
{
b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.SocialComment)), Prefix.DbSchema);
b.ConfigureByConvention();
b.Property(x => x.Content).IsRequired().HasMaxLength(8000);
b.HasOne(x => x.SocialPost)
.WithMany(x => x.Comments)
.HasForeignKey(x => x.SocialPostId)
.OnDelete(DeleteBehavior.Cascade);
});
// 🔹 SocialLike
builder.Entity<SocialLike>(b =>
{
b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.SocialLike)), Prefix.DbSchema);
b.ConfigureByConvention();
b.HasOne(x => x.SocialPost)
.WithMany(x => x.Likes)
.HasForeignKey(x => x.SocialPostId)
.OnDelete(DeleteBehavior.Cascade);
});
}
}

View file

@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore;
namespace Kurs.Platform.Migrations
{
[DbContext(typeof(PlatformDbContext))]
[Migration("20251027142130_Initial")]
[Migration("20251028102645_Initial")]
partial class Initial
{
/// <inheritdoc />
@ -7877,6 +7877,385 @@ namespace Kurs.Platform.Migrations
b.ToTable("T_Adm_SkillType", (string)null);
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialComment", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<string>("Content")
.IsRequired()
.HasMaxLength(8000)
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<Guid?>("EmployeeId")
.HasColumnType("uniqueidentifier");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<Guid>("SocialPostId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("EmployeeId");
b.HasIndex("SocialPostId");
b.ToTable("T_Net_SocialComment", (string)null);
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialLike", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<Guid?>("EmployeeId")
.HasColumnType("uniqueidentifier");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<Guid>("SocialPostId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("EmployeeId");
b.HasIndex("SocialPostId");
b.ToTable("T_Net_SocialLike", (string)null);
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialLocation", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<string>("Address")
.HasMaxLength(512)
.HasColumnType("nvarchar(512)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<double?>("Lat")
.HasColumnType("float");
b.Property<double?>("Lng")
.HasColumnType("float");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("PlaceId")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<Guid>("SocialPostId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("SocialPostId")
.IsUnique();
b.ToTable("T_Net_SocialLocation", (string)null);
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialMedia", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<DateTime?>("PollEndsAt")
.HasColumnType("datetime2");
b.Property<string>("PollQuestion")
.HasColumnType("nvarchar(max)");
b.Property<int?>("PollTotalVotes")
.HasColumnType("int");
b.Property<string>("PollUserVoteId")
.HasColumnType("nvarchar(max)");
b.Property<Guid>("SocialPostId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.Property<string>("Type")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.PrimitiveCollection<string>("Urls")
.HasMaxLength(2000)
.HasColumnType("nvarchar(2000)");
b.HasKey("Id");
b.HasIndex("SocialPostId")
.IsUnique();
b.ToTable("T_Net_SocialMedia", (string)null);
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialPollOption", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<Guid>("SocialMediaId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.Property<string>("Text")
.IsRequired()
.HasMaxLength(512)
.HasColumnType("nvarchar(512)");
b.Property<int>("Votes")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("SocialMediaId");
b.ToTable("T_Net_SocialPollOption", (string)null);
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialPost", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<string>("Content")
.IsRequired()
.HasMaxLength(4000)
.HasColumnType("nvarchar(4000)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<Guid?>("EmployeeId")
.HasColumnType("uniqueidentifier");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<bool>("IsLiked")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false);
b.Property<bool>("IsOwnPost")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false);
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<int>("LikeCount")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasDefaultValue(0);
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("EmployeeId");
b.ToTable("T_Net_SocialPost", (string)null);
});
modelBuilder.Entity("Kurs.Platform.Entities.Source", b =>
{
b.Property<Guid>("Id")
@ -11633,6 +12012,82 @@ namespace Kurs.Platform.Migrations
b.Navigation("SkillType");
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialComment", b =>
{
b.HasOne("Kurs.Platform.Entities.Employee", "Employee")
.WithMany()
.HasForeignKey("EmployeeId");
b.HasOne("Kurs.Platform.Entities.SocialPost", "SocialPost")
.WithMany("Comments")
.HasForeignKey("SocialPostId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Employee");
b.Navigation("SocialPost");
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialLike", b =>
{
b.HasOne("Kurs.Platform.Entities.Employee", "Employee")
.WithMany()
.HasForeignKey("EmployeeId");
b.HasOne("Kurs.Platform.Entities.SocialPost", "SocialPost")
.WithMany("Likes")
.HasForeignKey("SocialPostId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Employee");
b.Navigation("SocialPost");
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialLocation", b =>
{
b.HasOne("Kurs.Platform.Entities.SocialPost", "SocialPost")
.WithOne("Location")
.HasForeignKey("Kurs.Platform.Entities.SocialLocation", "SocialPostId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("SocialPost");
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialMedia", b =>
{
b.HasOne("Kurs.Platform.Entities.SocialPost", "SocialPost")
.WithOne("Media")
.HasForeignKey("Kurs.Platform.Entities.SocialMedia", "SocialPostId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("SocialPost");
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialPollOption", b =>
{
b.HasOne("Kurs.Platform.Entities.SocialMedia", "SocialMedia")
.WithMany("PollOptions")
.HasForeignKey("SocialMediaId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("SocialMedia");
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialPost", b =>
{
b.HasOne("Kurs.Platform.Entities.Employee", "Employee")
.WithMany()
.HasForeignKey("EmployeeId");
b.Navigation("Employee");
});
modelBuilder.Entity("Kurs.Platform.Entities.SurveyAnswer", b =>
{
b.HasOne("Kurs.Platform.Entities.SurveyQuestion", "Question")
@ -12039,6 +12494,22 @@ namespace Kurs.Platform.Migrations
b.Navigation("Skills");
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialMedia", b =>
{
b.Navigation("PollOptions");
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialPost", b =>
{
b.Navigation("Comments");
b.Navigation("Likes");
b.Navigation("Location");
b.Navigation("Media");
});
modelBuilder.Entity("Kurs.Platform.Entities.Survey", b =>
{
b.Navigation("Questions");

View file

@ -4466,6 +4466,35 @@ namespace Kurs.Platform.Migrations
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "T_Net_SocialPost",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
EmployeeId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
Content = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: false),
LikeCount = table.Column<int>(type: "int", nullable: false, defaultValue: 0),
IsLiked = table.Column<bool>(type: "bit", nullable: false, defaultValue: false),
IsOwnPost = table.Column<bool>(type: "bit", nullable: false, defaultValue: false),
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false),
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
LastModificationTime = table.Column<DateTime>(type: "datetime2", nullable: true),
LastModifierId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
IsDeleted = table.Column<bool>(type: "bit", nullable: false, defaultValue: false),
DeleterId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
DeletionTime = table.Column<DateTime>(type: "datetime2", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_T_Net_SocialPost", x => x.Id);
table.ForeignKey(
name: "FK_T_Net_SocialPost_T_Hr_Employee_EmployeeId",
column: x => x.EmployeeId,
principalTable: "T_Hr_Employee",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "T_Net_Visitor",
columns: table => new
@ -4536,6 +4565,162 @@ namespace Kurs.Platform.Migrations
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "T_Net_SocialComment",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
SocialPostId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
EmployeeId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
Content = table.Column<string>(type: "nvarchar(max)", maxLength: 8000, nullable: false),
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false),
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
LastModificationTime = table.Column<DateTime>(type: "datetime2", nullable: true),
LastModifierId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
IsDeleted = table.Column<bool>(type: "bit", nullable: false, defaultValue: false),
DeleterId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
DeletionTime = table.Column<DateTime>(type: "datetime2", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_T_Net_SocialComment", x => x.Id);
table.ForeignKey(
name: "FK_T_Net_SocialComment_T_Hr_Employee_EmployeeId",
column: x => x.EmployeeId,
principalTable: "T_Hr_Employee",
principalColumn: "Id");
table.ForeignKey(
name: "FK_T_Net_SocialComment_T_Net_SocialPost_SocialPostId",
column: x => x.SocialPostId,
principalTable: "T_Net_SocialPost",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "T_Net_SocialLike",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
SocialPostId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
EmployeeId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false),
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
LastModificationTime = table.Column<DateTime>(type: "datetime2", nullable: true),
LastModifierId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
IsDeleted = table.Column<bool>(type: "bit", nullable: false, defaultValue: false),
DeleterId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
DeletionTime = table.Column<DateTime>(type: "datetime2", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_T_Net_SocialLike", x => x.Id);
table.ForeignKey(
name: "FK_T_Net_SocialLike_T_Hr_Employee_EmployeeId",
column: x => x.EmployeeId,
principalTable: "T_Hr_Employee",
principalColumn: "Id");
table.ForeignKey(
name: "FK_T_Net_SocialLike_T_Net_SocialPost_SocialPostId",
column: x => x.SocialPostId,
principalTable: "T_Net_SocialPost",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "T_Net_SocialLocation",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
SocialPostId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
Address = table.Column<string>(type: "nvarchar(512)", maxLength: 512, nullable: true),
Lat = table.Column<double>(type: "float", nullable: true),
Lng = table.Column<double>(type: "float", nullable: true),
PlaceId = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false),
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
LastModificationTime = table.Column<DateTime>(type: "datetime2", nullable: true),
LastModifierId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
IsDeleted = table.Column<bool>(type: "bit", nullable: false, defaultValue: false),
DeleterId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
DeletionTime = table.Column<DateTime>(type: "datetime2", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_T_Net_SocialLocation", x => x.Id);
table.ForeignKey(
name: "FK_T_Net_SocialLocation_T_Net_SocialPost_SocialPostId",
column: x => x.SocialPostId,
principalTable: "T_Net_SocialPost",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "T_Net_SocialMedia",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
SocialPostId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Type = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: false),
Urls = table.Column<string>(type: "nvarchar(2000)", maxLength: 2000, nullable: true),
PollQuestion = table.Column<string>(type: "nvarchar(max)", nullable: true),
PollTotalVotes = table.Column<int>(type: "int", nullable: true),
PollEndsAt = table.Column<DateTime>(type: "datetime2", nullable: true),
PollUserVoteId = table.Column<string>(type: "nvarchar(max)", nullable: true),
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false),
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
LastModificationTime = table.Column<DateTime>(type: "datetime2", nullable: true),
LastModifierId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
IsDeleted = table.Column<bool>(type: "bit", nullable: false, defaultValue: false),
DeleterId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
DeletionTime = table.Column<DateTime>(type: "datetime2", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_T_Net_SocialMedia", x => x.Id);
table.ForeignKey(
name: "FK_T_Net_SocialMedia_T_Net_SocialPost_SocialPostId",
column: x => x.SocialPostId,
principalTable: "T_Net_SocialPost",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "T_Net_SocialPollOption",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
SocialMediaId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Text = table.Column<string>(type: "nvarchar(512)", maxLength: 512, nullable: false),
Votes = table.Column<int>(type: "int", nullable: false),
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false),
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
LastModificationTime = table.Column<DateTime>(type: "datetime2", nullable: true),
LastModifierId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
IsDeleted = table.Column<bool>(type: "bit", nullable: false, defaultValue: false),
DeleterId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
DeletionTime = table.Column<DateTime>(type: "datetime2", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_T_Net_SocialPollOption", x => x.Id);
table.ForeignKey(
name: "FK_T_Net_SocialPollOption_T_Net_SocialMedia_SocialMediaId",
column: x => x.SocialMediaId,
principalTable: "T_Net_SocialMedia",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_AbpAuditLogActions_AuditLogId",
table: "AbpAuditLogActions",
@ -5255,6 +5440,48 @@ namespace Kurs.Platform.Migrations
table: "T_Net_Reservation",
column: "EmployeeId");
migrationBuilder.CreateIndex(
name: "IX_T_Net_SocialComment_EmployeeId",
table: "T_Net_SocialComment",
column: "EmployeeId");
migrationBuilder.CreateIndex(
name: "IX_T_Net_SocialComment_SocialPostId",
table: "T_Net_SocialComment",
column: "SocialPostId");
migrationBuilder.CreateIndex(
name: "IX_T_Net_SocialLike_EmployeeId",
table: "T_Net_SocialLike",
column: "EmployeeId");
migrationBuilder.CreateIndex(
name: "IX_T_Net_SocialLike_SocialPostId",
table: "T_Net_SocialLike",
column: "SocialPostId");
migrationBuilder.CreateIndex(
name: "IX_T_Net_SocialLocation_SocialPostId",
table: "T_Net_SocialLocation",
column: "SocialPostId",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_T_Net_SocialMedia_SocialPostId",
table: "T_Net_SocialMedia",
column: "SocialPostId",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_T_Net_SocialPollOption_SocialMediaId",
table: "T_Net_SocialPollOption",
column: "SocialMediaId");
migrationBuilder.CreateIndex(
name: "IX_T_Net_SocialPost_EmployeeId",
table: "T_Net_SocialPost",
column: "EmployeeId");
migrationBuilder.CreateIndex(
name: "IX_T_Net_Visitor_EmployeeId",
table: "T_Net_Visitor",
@ -5615,6 +5842,18 @@ namespace Kurs.Platform.Migrations
migrationBuilder.DropTable(
name: "T_Net_ShuttleRoute");
migrationBuilder.DropTable(
name: "T_Net_SocialComment");
migrationBuilder.DropTable(
name: "T_Net_SocialLike");
migrationBuilder.DropTable(
name: "T_Net_SocialLocation");
migrationBuilder.DropTable(
name: "T_Net_SocialPollOption");
migrationBuilder.DropTable(
name: "T_Net_Visitor");
@ -5756,6 +5995,9 @@ namespace Kurs.Platform.Migrations
migrationBuilder.DropTable(
name: "T_Net_Training");
migrationBuilder.DropTable(
name: "T_Net_SocialMedia");
migrationBuilder.DropTable(
name: "T_Sas_CustomEntity");
@ -5795,6 +6037,9 @@ namespace Kurs.Platform.Migrations
migrationBuilder.DropTable(
name: "T_Hr_Survey");
migrationBuilder.DropTable(
name: "T_Net_SocialPost");
migrationBuilder.DropTable(
name: "T_Sas_ReportCategory");

View file

@ -7874,6 +7874,385 @@ namespace Kurs.Platform.Migrations
b.ToTable("T_Adm_SkillType", (string)null);
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialComment", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<string>("Content")
.IsRequired()
.HasMaxLength(8000)
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<Guid?>("EmployeeId")
.HasColumnType("uniqueidentifier");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<Guid>("SocialPostId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("EmployeeId");
b.HasIndex("SocialPostId");
b.ToTable("T_Net_SocialComment", (string)null);
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialLike", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<Guid?>("EmployeeId")
.HasColumnType("uniqueidentifier");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<Guid>("SocialPostId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("EmployeeId");
b.HasIndex("SocialPostId");
b.ToTable("T_Net_SocialLike", (string)null);
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialLocation", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<string>("Address")
.HasMaxLength(512)
.HasColumnType("nvarchar(512)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<double?>("Lat")
.HasColumnType("float");
b.Property<double?>("Lng")
.HasColumnType("float");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("PlaceId")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<Guid>("SocialPostId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("SocialPostId")
.IsUnique();
b.ToTable("T_Net_SocialLocation", (string)null);
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialMedia", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<DateTime?>("PollEndsAt")
.HasColumnType("datetime2");
b.Property<string>("PollQuestion")
.HasColumnType("nvarchar(max)");
b.Property<int?>("PollTotalVotes")
.HasColumnType("int");
b.Property<string>("PollUserVoteId")
.HasColumnType("nvarchar(max)");
b.Property<Guid>("SocialPostId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.Property<string>("Type")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.PrimitiveCollection<string>("Urls")
.HasMaxLength(2000)
.HasColumnType("nvarchar(2000)");
b.HasKey("Id");
b.HasIndex("SocialPostId")
.IsUnique();
b.ToTable("T_Net_SocialMedia", (string)null);
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialPollOption", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<Guid>("SocialMediaId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.Property<string>("Text")
.IsRequired()
.HasMaxLength(512)
.HasColumnType("nvarchar(512)");
b.Property<int>("Votes")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("SocialMediaId");
b.ToTable("T_Net_SocialPollOption", (string)null);
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialPost", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<string>("Content")
.IsRequired()
.HasMaxLength(4000)
.HasColumnType("nvarchar(4000)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<Guid?>("EmployeeId")
.HasColumnType("uniqueidentifier");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<bool>("IsLiked")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false);
b.Property<bool>("IsOwnPost")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false);
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<int>("LikeCount")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasDefaultValue(0);
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("EmployeeId");
b.ToTable("T_Net_SocialPost", (string)null);
});
modelBuilder.Entity("Kurs.Platform.Entities.Source", b =>
{
b.Property<Guid>("Id")
@ -11630,6 +12009,82 @@ namespace Kurs.Platform.Migrations
b.Navigation("SkillType");
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialComment", b =>
{
b.HasOne("Kurs.Platform.Entities.Employee", "Employee")
.WithMany()
.HasForeignKey("EmployeeId");
b.HasOne("Kurs.Platform.Entities.SocialPost", "SocialPost")
.WithMany("Comments")
.HasForeignKey("SocialPostId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Employee");
b.Navigation("SocialPost");
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialLike", b =>
{
b.HasOne("Kurs.Platform.Entities.Employee", "Employee")
.WithMany()
.HasForeignKey("EmployeeId");
b.HasOne("Kurs.Platform.Entities.SocialPost", "SocialPost")
.WithMany("Likes")
.HasForeignKey("SocialPostId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Employee");
b.Navigation("SocialPost");
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialLocation", b =>
{
b.HasOne("Kurs.Platform.Entities.SocialPost", "SocialPost")
.WithOne("Location")
.HasForeignKey("Kurs.Platform.Entities.SocialLocation", "SocialPostId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("SocialPost");
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialMedia", b =>
{
b.HasOne("Kurs.Platform.Entities.SocialPost", "SocialPost")
.WithOne("Media")
.HasForeignKey("Kurs.Platform.Entities.SocialMedia", "SocialPostId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("SocialPost");
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialPollOption", b =>
{
b.HasOne("Kurs.Platform.Entities.SocialMedia", "SocialMedia")
.WithMany("PollOptions")
.HasForeignKey("SocialMediaId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("SocialMedia");
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialPost", b =>
{
b.HasOne("Kurs.Platform.Entities.Employee", "Employee")
.WithMany()
.HasForeignKey("EmployeeId");
b.Navigation("Employee");
});
modelBuilder.Entity("Kurs.Platform.Entities.SurveyAnswer", b =>
{
b.HasOne("Kurs.Platform.Entities.SurveyQuestion", "Question")
@ -12036,6 +12491,22 @@ namespace Kurs.Platform.Migrations
b.Navigation("Skills");
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialMedia", b =>
{
b.Navigation("PollOptions");
});
modelBuilder.Entity("Kurs.Platform.Entities.SocialPost", b =>
{
b.Navigation("Comments");
b.Navigation("Likes");
b.Navigation("Location");
b.Navigation("Media");
});
modelBuilder.Entity("Kurs.Platform.Entities.Survey", b =>
{
b.Navigation("Questions");

View file

@ -100,9 +100,7 @@
"props": null,
"description": null,
"isActive": true,
"dependencies": [
"AxiosListComponent"
]
"dependencies": ["AxiosListComponent"]
}
],
"ReportCategories": [
@ -2211,12 +2209,7 @@
"minSalary": 80000,
"maxSalary": 120000,
"currencyCode": "USD",
"requiredSkills": [
"JavaScript",
"TypeScript",
"React",
"Node.js"
],
"requiredSkills": ["JavaScript", "TypeScript", "React", "Node.js"],
"responsibilities": [
"Develop frontend and backend applications",
"Write clean and maintainable code",
@ -3874,5 +3867,156 @@
"Text": "Hibrit (Karma)",
"Order": 3
}
],
"SocialPosts": [
{
"content": "Yeni proje üzerinde çalışıyoruz! React ve TypeScript ile harika bir deneyim oluşturuyoruz. Ekip çalışması harika gidiyor! 🚀",
"employeeCode": "EMP-002",
"likeCount": 24,
"isLiked": true,
"isOwnPost": false
},
{
"content": "Bu hafta sprint planlamasını yaptık. Ekibimizle birlikte yeni özellikleri değerlendirdik. Heyecan verici bir hafta olacak!",
"employeeCode": "EMP-001",
"likeCount": 18,
"isLiked": false,
"isOwnPost": true
},
{
"content": "Yeni tasarım sistemimizin ilk prototipini hazırladık! Kullanıcı deneyimini iyileştirmek için çok çalıştık. Geri bildirimlerinizi bekliyorum! 🎨",
"employeeCode": "EMP-003",
"likeCount": 42,
"isLiked": true,
"isOwnPost": false
},
{
"content": "CI/CD pipeline güncellememiz tamamlandı! Deployment süremiz %40 azaldı. Otomasyonun gücü 💪",
"employeeCode": "EMP-004",
"likeCount": 31,
"isLiked": false,
"isOwnPost": false
},
{
"content": "Ekip üyelerimize yeni eğitim programımızı duyurmak istiyorum! 🎓 React, TypeScript ve Modern Web Geliştirme konularında kapsamlı bir program hazırladık.",
"employeeCode": "EMP-007",
"likeCount": 56,
"isLiked": true,
"isOwnPost": false
},
{
"content": "Bugün müşteri ile harika bir toplantı yaptık! Yeni projenin detaylarını konuştuk. 🎯",
"employeeCode": "EMP-002",
"likeCount": 18,
"isLiked": false,
"isOwnPost": false
}
],
"SocialLocations": [
{
"postContent": "Yeni proje üzerinde çalışıyoruz! React ve TypeScript ile harika bir deneyim oluşturuyoruz. Ekip çalışması harika gidiyor! 🚀",
"name": "Taksim Meydanı",
"address": "Taksim, Gümüşsuyu Mahallesi, 34437 Beyoğlu/İstanbul",
"lat": 41.0369,
"lng": 28.985,
"placeId": "ChIJBQRGmL25yhQRXwqRTHAwAAQ"
},
{
"postContent": "Bugün müşteri ile harika bir toplantı yaptık! Yeni projenin detaylarını konuştuk. 🎯",
"name": "Sultanahmet Meydanı",
"address": "Sultanahmet Mahallesi, 34122 Fatih/İstanbul",
"lat": 41.0058,
"lng": 28.9768,
"placeId": "ChIJ7fVVZiy5yhQRzsXXXXXXXXk"
}
],
"SocialMedias": [
{
"postContent": "Yeni proje üzerinde çalışıyoruz! React ve TypeScript ile harika bir deneyim oluşturuyoruz. Ekip çalışması harika gidiyor! 🚀",
"type": "image",
"urls": [
"https://images.unsplash.com/photo-1633356122544-f134324a6cee?w=800&q=80"
]
},
{
"postContent": "Bu hafta sprint planlamasını yaptık. Ekibimizle birlikte yeni özellikleri değerlendirdik. Heyecan verici bir hafta olacak!",
"type": "poll",
"pollQuestion": "Hangi özelliği öncelikli olarak geliştirmeliyiz?",
"pollOptions": [
{ "text": "Kullanıcı profilleri", "votes": 12 },
{ "text": "Bildirim sistemi", "votes": 8 },
{ "text": "Mesajlaşma", "votes": 15 },
{ "text": "Raporlama", "votes": 5 }
],
"pollTotalVotes": 40,
"pollEndsAt": "2024-10-20T23:59:59",
"pollUserVoteId": "p3"
},
{
"postContent": "Yeni tasarım sistemimizin ilk prototipini hazırladık! Kullanıcı deneyimini iyileştirmek için çok çalıştık. Geri bildirimlerinizi bekliyorum! 🎨",
"type": "image",
"urls": [
"https://images.unsplash.com/photo-1561070791-2526d30994b5?w=800&q=80",
"https://images.unsplash.com/photo-1586717799252-bd134ad00e26?w=800&q=80",
"https://images.unsplash.com/photo-1609921212029-bb5a28e60960?w=800&q=80"
]
},
{
"postContent": "CI/CD pipeline güncellememiz tamamlandı! Deployment süremiz %40 azaldı. Otomasyonun gücü 💪",
"type": "video",
"urls": ["https://www.w3schools.com/html/mov_bbb.mp4"]
}
],
"SocialComments": [
{
"postContent": "Yeni proje üzerinde çalışıyoruz! React ve TypeScript ile harika bir deneyim oluşturuyoruz. Ekip çalışması harika gidiyor! 🚀",
"employeeCode": "EMP-003",
"content": "Harika görünüyor! Başarılar 👏"
},
{
"postContent": "Yeni proje üzerinde çalışıyoruz! React ve TypeScript ile harika bir deneyim oluşturuyoruz. Ekip çalışması harika gidiyor! 🚀",
"employeeCode": "EMP-003",
"content": "TypeScript gerçekten fark yaratıyor!"
},
{
"postContent": "Bu hafta sprint planlamasını yaptık. Ekibimizle birlikte yeni özellikleri değerlendirdik. Heyecan verici bir hafta olacak!",
"employeeCode": "EMP-004",
"content": "Mesajlaşma özelliğine kesinlikle ihtiyacımız var!"
},
{
"postContent": "Yeni tasarım sistemimizin ilk prototipini hazırladık! Kullanıcı deneyimini iyileştirmek için çok çalıştık. Geri bildirimlerinizi bekliyorum! 🎨",
"employeeCode": "EMP-005",
"content": "Tasarımlar çok şık! Renk paleti özellikle güzel 😍"
},
{
"postContent": "Yeni tasarım sistemimizin ilk prototipini hazırladık! Kullanıcı deneyimini iyileştirmek için çok çalıştık. Geri bildirimlerinizi bekliyorum! 🎨",
"employeeCode": "EMP-005",
"content": "Dark mode opsiyonu da olacak mı?"
},
{
"postContent": "CI/CD pipeline güncellememiz tamamlandı! Deployment süremiz %40 azaldı. Otomasyonun gücü 💪",
"employeeCode": "EMP-006",
"content": "Harika iş! Detayları paylaşabilir misin?"
},
{
"postContent": "Ekip üyelerimize yeni eğitim programımızı duyurmak istiyorum! 🎓 React, TypeScript ve Modern Web Geliştirme konularında kapsamlı bir program hazırladık.",
"employeeCode": "EMP-001",
"content": "Ne zaman başlıyor?"
},
{
"postContent": "Ekip üyelerimize yeni eğitim programımızı duyurmak istiyorum! 🎓 React, TypeScript ve Modern Web Geliştirme konularında kapsamlı bir program hazırladık.",
"employeeCode": "EMP-005",
"content": "Gelecek hafta başlıyoruz! Kayıt linki mail ile paylaşılacak."
}
],
"SocialLikes": [
{
"postContent": "Yeni proje üzerinde çalışıyoruz! React ve TypeScript ile harika bir deneyim oluşturuyoruz. Ekip çalışması harika gidiyor! 🚀",
"employeeCode": "EMP-002"
},
{
"postContent": "Yeni tasarım sistemimizin ilk prototipini hazırladık! Kullanıcı deneyimini iyileştirmek için çok çalıştık. Geri bildirimlerinizi bekliyorum! 🎨",
"employeeCode": "EMP-003"
}
]
}

View file

@ -13,7 +13,6 @@ using Microsoft.EntityFrameworkCore;
using System.Linq;
using System.Collections.Generic;
using Volo.Abp.Identity;
using Azure.Core;
namespace Kurs.Platform.Data.Seeds;
@ -83,6 +82,11 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
private readonly IRepository<Survey, Guid> _surveyRepository;
private readonly IRepository<SurveyQuestion, Guid> _surveyQuestionRepository;
private readonly IRepository<SurveyQuestionOption, Guid> _surveyQuestionOptionRepository;
private readonly IRepository<SocialPost, Guid> _socialPostRepository;
private readonly IRepository<SocialLocation, Guid> _socialLocationRepository;
private readonly IRepository<SocialMedia, Guid> _socialMediaRepository;
private readonly IRepository<SocialComment, Guid> _socialCommentRepository;
private readonly IRepository<SocialLike, Guid> _socialLikeRepository;
public TenantDataSeeder(
IRepository<IdentityUser, Guid> repositoryUser,
@ -148,7 +152,12 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
IRepository<Expense, Guid> expenseRepository,
IRepository<Survey, Guid> surveyRepository,
IRepository<SurveyQuestion, Guid> surveyQuestionRepository,
IRepository<SurveyQuestionOption, Guid> surveyQuestionOptionRepository
IRepository<SurveyQuestionOption, Guid> surveyQuestionOptionRepository,
IRepository<SocialPost, Guid> socialPostRepository,
IRepository<SocialLocation, Guid> socialLocationRepository,
IRepository<SocialMedia, Guid> socialMediaRepository,
IRepository<SocialComment, Guid> socialCommentRepository,
IRepository<SocialLike, Guid> socialLikeRepository
)
{
_repositoryUser = repositoryUser;
@ -216,6 +225,11 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
_surveyRepository = surveyRepository;
_surveyQuestionRepository = surveyQuestionRepository;
_surveyQuestionOptionRepository = surveyQuestionOptionRepository;
_socialPostRepository = socialPostRepository;
_socialLocationRepository = socialLocationRepository;
_socialMediaRepository = socialMediaRepository;
_socialCommentRepository = socialCommentRepository;
_socialLikeRepository = socialLikeRepository;
}
private static IConfigurationRoot BuildConfiguration()
@ -1397,5 +1411,106 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
Order = item.Order
}, autoSave: true);
}
foreach (var item in items.SocialPosts)
{
var exists = await _socialPostRepository.AnyAsync(x => x.Content == item.Content);
if (exists)
continue;
var employee = await _employeeRepository.FirstOrDefaultAsync(x => x.Code == item.EmployeeCode);
await _socialPostRepository.InsertAsync(new SocialPost
{
EmployeeId = employee != null ? employee.Id : null,
Content = item.Content,
LikeCount = item.LikeCount,
IsLiked = item.IsLiked,
IsOwnPost = item.IsOwnPost
}, autoSave: true);
}
foreach (var item in items.SocialLocations)
{
var post = await _socialPostRepository.FirstOrDefaultAsync(x => x.Content == item.PostContent);
if (post == null)
continue;
var exists = await _socialLocationRepository.AnyAsync(x => x.SocialPostId == post.Id && x.Name == item.Name);
if (exists)
continue;
await _socialLocationRepository.InsertAsync(new SocialLocation
{
SocialPostId = post != null ? post.Id : Guid.Empty,
Name = item.Name,
Address = item.Address,
Lat = item.Lat,
Lng = item.Lng,
PlaceId = item.PlaceId
}, autoSave: true);
}
foreach (var item in items.SocialMedias)
{
var post = await _socialPostRepository.FirstOrDefaultAsync(x => x.Content == item.PostContent);
if (post == null)
continue;
var exists = await _socialMediaRepository.AnyAsync(x => x.SocialPostId == post.Id);
if (exists)
continue;
await _socialMediaRepository.InsertAsync(new SocialMedia
{
SocialPostId = post != null ? post.Id : Guid.Empty,
Type = item.Type,
Urls = item.Urls,
PollQuestion = item.PollQuestion,
PollTotalVotes = item.PollTotalVotes,
PollEndsAt = item.PollEndsAt,
PollUserVoteId = item.PollUserVoteId
}, autoSave: true);
}
foreach (var item in items.SocialComments)
{
var post = await _socialPostRepository.FirstOrDefaultAsync(x => x.Content == item.PostContent);
if (post == null)
continue;
var exists = await _socialCommentRepository.AnyAsync(x => x.SocialPostId == post.Id && x.Content == item.Content);
if (exists)
continue;
var employee = await _employeeRepository.FirstOrDefaultAsync(x => x.Code == item.EmployeeCode);
await _socialCommentRepository.InsertAsync(new SocialComment
{
EmployeeId = employee != null ? employee.Id : null,
SocialPostId = post != null ? post.Id : Guid.Empty,
Content = item.Content
}, autoSave: true);
}
foreach (var item in items.SocialLikes)
{
var post = await _socialPostRepository.FirstOrDefaultAsync(x => x.Content == item.PostContent);
if (post == null)
continue;
var exists = await _socialLikeRepository.AnyAsync(x => x.SocialPostId == post.Id);
if (exists)
continue;
var employee = await _employeeRepository.FirstOrDefaultAsync(x => x.Code == item.EmployeeCode);
await _socialLikeRepository.InsertAsync(new SocialLike
{
SocialPostId = post != null ? post.Id : Guid.Empty,
EmployeeId = employee != null ? employee.Id : null
}, autoSave: true);
}
}
}

View file

@ -71,6 +71,63 @@ public class TenantSeederDto
public List<SurveySeedDto> Surveys { get; set; }
public List<SurveyQuestionSeedDto> SurveyQuestions { get; set; }
public List<SurveyQuestionOptionSeedDto> SurveyQuestionOptions { get; set; }
public List<SocialPostSeedDto> SocialPosts { get; set; }
public List<SocialLocationSeedDto> SocialLocations { get; set; }
public List<SocialMediaSeedDto> SocialMedias { get; set; }
public List<SocialCommentSeedDto> SocialComments { get; set; }
public List<SocialLikeSeedDto> SocialLikes { get; set; }
}
public class SocialPostSeedDto
{
public string Content { get; set; }
public string EmployeeCode { get; set; }
public int LikeCount { get; set; }
public bool IsLiked { get; set; }
public bool IsOwnPost { get; set; }
}
public class SocialLocationSeedDto
{
public string PostContent { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public double? Lat { get; set; }
public double? Lng { get; set; }
public string PlaceId { get; set; }
}
public class SocialMediaSeedDto
{
public string PostContent { get; set; }
public string Type { get; set; }
public string[] Urls { get; set; }
public string PollQuestion { get; set; }
public int? PollTotalVotes { get; set; }
public DateTime? PollEndsAt { get; set; }
public string PollUserVoteId { get; set; }
public List<SocialPollOptionSeedDto> PollOptions { get; set; }
}
public class SocialPollOptionSeedDto
{
public string Text { get; set; }
public int Votes { get; set; }
}
public class SocialCommentSeedDto
{
public string PostContent { get; set; }
public string EmployeeCode { get; set; }
public string Content { get; set; }
}
public class SocialLikeSeedDto
{
public string PostContent { get; set; }
public string EmployeeCode { get; set; }
}
public class SurveySeedDto

View file

@ -14,195 +14,6 @@ import {
SocialPost,
} from '@/types/intranet'
// Mevcut çalışanları kullan - "Siz" kullanıcısı mockEmployees[0] (Ali Öztürk) olacak
const currentUser = { ...mockEmployees[0], fullName: 'Siz' } // Ali Öztürk'ü "Siz" olarak kullan
export const mockSocialPosts: SocialPost[] = [
{
id: '1',
author: mockEmployees[2], // Mehmet Yılmaz
content:
'Yeni proje üzerinde çalışıyoruz! React ve TypeScript ile harika bir deneyim oluşturuyoruz. Ekip çalışması harika gidiyor! 🚀',
creationTime: new Date('2024-10-15T10:30:00'),
location: {
id: '1',
name: 'Taksim Meydanı',
address: 'Taksim, Gümüşsuyu Mahallesi, 34437 Beyoğlu/İstanbul',
lat: 41.0369,
lng: 28.985,
placeId: 'ChIJBQRGmL25yhQRXwqRTHAwAAQ',
},
media: {
type: 'image',
url: 'https://images.unsplash.com/photo-1633356122544-f134324a6cee?w=800&q=80',
},
likes: {
count: 24,
isLiked: true,
users: [mockEmployees[1], mockEmployees[3]], // Ayşe Kaya, Selin Demir
},
comments: [
{
id: 'c1',
author: mockEmployees[1], // Ayşe Kaya
content: 'Harika görünüyor! Başarılar 👏',
creationTime: new Date('2024-10-15T11:00:00'),
},
{
id: 'c2',
author: mockEmployees[3], // Selin Demir
content: 'TypeScript gerçekten fark yaratıyor!',
creationTime: new Date('2024-10-15T11:30:00'),
},
],
isOwnPost: false,
},
{
id: '2',
author: currentUser,
content:
'Bu hafta sprint planlamasını yaptık. Ekibimizle birlikte yeni özellikleri değerlendirdik. Heyecan verici bir hafta olacak!',
creationTime: new Date('2024-10-16T09:00:00'),
media: {
type: 'poll',
poll: {
question: 'Hangi özelliği öncelikli olarak geliştirmeliyiz?',
options: [
{ id: 'p1', text: 'Kullanıcı profilleri', votes: 12 },
{ id: 'p2', text: 'Bildirim sistemi', votes: 8 },
{ id: 'p3', text: 'Mesajlaşma', votes: 15 },
{ id: 'p4', text: 'Raporlama', votes: 5 },
],
totalVotes: 40,
endsAt: new Date('2024-10-20T23:59:59'),
userVote: 'p3',
},
},
likes: {
count: 18,
isLiked: false,
users: [],
},
comments: [
{
id: 'c3',
author: mockEmployees[4], // Ahmet Çelik
content: 'Mesajlaşma özelliğine kesinlikle ihtiyacımız var!',
creationTime: new Date('2024-10-16T10:15:00'),
},
],
isOwnPost: true,
},
{
id: '3',
author: mockEmployees[5], // Zeynep Arslan
content:
'Yeni tasarım sistemimizin ilk prototipini hazırladık! Kullanıcı deneyimini iyileştirmek için çok çalıştık. Geri bildirimlerinizi bekliyorum! 🎨',
creationTime: new Date('2024-10-17T14:20:00'),
media: {
type: 'image',
urls: [
'https://images.unsplash.com/photo-1561070791-2526d30994b5?w=800&q=80',
'https://images.unsplash.com/photo-1586717799252-bd134ad00e26?w=800&q=80',
'https://images.unsplash.com/photo-1609921212029-bb5a28e60960?w=800&q=80',
],
},
likes: {
count: 42,
isLiked: true,
users: [mockEmployees[2]], // Mehmet Yılmaz
},
comments: [
{
id: 'c4',
author: mockEmployees[6], // Burak Koç
content: 'Tasarımlar çok şık! Renk paleti özellikle güzel 😍',
creationTime: new Date('2024-10-17T15:00:00'),
},
{
id: 'c5',
author: mockEmployees[7], // Elif Şahin
content: 'Dark mode opsiyonu da olacak mı?',
creationTime: new Date('2024-10-17T15:30:00'),
},
],
isOwnPost: false,
},
{
id: '4',
author: mockEmployees[6], // Burak Koç
content:
'CI/CD pipeline güncellememiz tamamlandı! Deployment süremiz %40 azaldı. Otomasyonun gücü 💪',
creationTime: new Date('2024-10-18T08:45:00'),
media: {
type: 'video',
url: 'https://www.w3schools.com/html/mov_bbb.mp4',
},
likes: {
count: 31,
isLiked: false,
users: [],
},
comments: [
{
id: 'c6',
author: mockEmployees[8], // Canan Öztürk
content: 'Harika iş! Detayları paylaşabilir misin?',
creationTime: new Date('2024-10-18T09:15:00'),
},
],
isOwnPost: false,
},
{
id: '5',
author: mockEmployees[7], // Elif Şahin
content:
'Ekip üyelerimize yeni eğitim programımızı duyurmak istiyorum! 🎓 React, TypeScript ve Modern Web Geliştirme konularında kapsamlı bir program hazırladık.',
creationTime: new Date('2024-10-14T16:00:00'),
likes: {
count: 56,
isLiked: true,
users: [],
},
comments: [
{
id: 'c7',
author: mockEmployees[2], // Mehmet Yılmaz
content: 'Ne zaman başlıyor?',
creationTime: new Date('2024-10-14T16:30:00'),
},
{
id: 'c8',
author: mockEmployees[7], // Elif Şahin
content: 'Gelecek hafta başlıyoruz! Kayıt linki mail ile paylaşılacak.',
creationTime: new Date('2024-10-14T17:00:00'),
},
],
isOwnPost: false,
},
{
id: '6',
author: mockEmployees[9], // Murat Aydın
content: 'Bugün müşteri ile harika bir toplantı yaptık! Yeni projenin detaylarını konuştuk. 🎯',
creationTime: new Date('2024-10-17T14:00:00'),
location: {
id: '4',
name: 'Sultanahmet Meydanı',
address: 'Sultanahmet Mahallesi, 34122 Fatih/İstanbul',
lat: 41.0058,
lng: 28.9768,
placeId: 'ChIJ7fVVZiy5yhQRzsXXXXXXXXk',
},
likes: {
count: 18,
isLiked: false,
users: [],
},
comments: [],
isOwnPost: false,
},
]
/////////////////////////////////////////////////////////////////////////////////////
///////EKLENENLER//////////
export const mockTrainings: Training[] = [
@ -1000,3 +811,178 @@ export const mockSurveys: Survey[] = [
isAnonymous: true,
},
]
// Mevcut çalışanları kullan - "Siz" kullanıcısı mockEmployees[0] (Ali Öztürk) olacak
const currentUser = { ...mockEmployees[0], fullName: 'Siz' } // Ali Öztürk'ü "Siz" olarak kullan
export const mockSocialPosts: SocialPost[] = [
{
id: '1',
creator: mockEmployees[2], // Mehmet Yılmaz
content:
'Yeni proje üzerinde çalışıyoruz! React ve TypeScript ile harika bir deneyim oluşturuyoruz. Ekip çalışması harika gidiyor! 🚀',
creationTime: new Date('2024-10-15T10:30:00'),
locationJson: JSON.stringify({
id: '1',
name: 'Taksim Meydanı',
address: 'Taksim, Gümüşsuyu Mahallesi, 34437 Beyoğlu/İstanbul',
lat: 41.0369,
lng: 28.985,
placeId: 'ChIJBQRGmL25yhQRXwqRTHAwAAQ',
}),
media: {
type: 'image',
urls: ['https://images.unsplash.com/photo-1633356122544-f134324a6cee?w=800&q=80'],
},
likeCount: 24,
isLiked: true,
likeUsers: [mockEmployees[1], mockEmployees[3]], // Ayşe Kaya, Selin Demir
comments: [
{
id: 'c1',
creator: mockEmployees[1], // Ayşe Kaya
content: 'Harika görünüyor! Başarılar 👏',
creationTime: new Date('2024-10-15T11:00:00'),
},
{
id: 'c2',
creator: mockEmployees[3], // Selin Demir
content: 'TypeScript gerçekten fark yaratıyor!',
creationTime: new Date('2024-10-15T11:30:00'),
},
],
isOwnPost: false,
},
{
id: '2',
creator: currentUser,
content:
'Bu hafta sprint planlamasını yaptık. Ekibimizle birlikte yeni özellikleri değerlendirdik. Heyecan verici bir hafta olacak!',
creationTime: new Date('2024-10-16T09:00:00'),
media: {
type: 'poll',
pollQuestion: 'Hangi özelliği öncelikli olarak geliştirmeliyiz?',
pollOptions: [
{ id: 'p1', text: 'Kullanıcı profilleri', votes: 12 },
{ id: 'p2', text: 'Bildirim sistemi', votes: 8 },
{ id: 'p3', text: 'Mesajlaşma', votes: 15 },
{ id: 'p4', text: 'Raporlama', votes: 5 },
],
pollTotalVotes: 40,
pollEndsAt: new Date('2024-10-20T23:59:59'),
pollUserVoteId: 'p3',
},
likeCount: 18,
isLiked: false,
likeUsers: [],
comments: [
{
id: 'c3',
creator: mockEmployees[4], // Ahmet Çelik
content: 'Mesajlaşma özelliğine kesinlikle ihtiyacımız var!',
creationTime: new Date('2024-10-16T10:15:00'),
},
],
isOwnPost: true,
},
{
id: '3',
creator: mockEmployees[5], // Zeynep Arslan
content:
'Yeni tasarım sistemimizin ilk prototipini hazırladık! Kullanıcı deneyimini iyileştirmek için çok çalıştık. Geri bildirimlerinizi bekliyorum! 🎨',
creationTime: new Date('2024-10-17T14:20:00'),
media: {
type: 'image',
urls: [
'https://images.unsplash.com/photo-1561070791-2526d30994b5?w=800&q=80',
'https://images.unsplash.com/photo-1586717799252-bd134ad00e26?w=800&q=80',
'https://images.unsplash.com/photo-1609921212029-bb5a28e60960?w=800&q=80',
],
},
likeCount: 42,
isLiked: true,
likeUsers: [mockEmployees[2]], // Mehmet Yılmaz
comments: [
{
id: 'c4',
creator: mockEmployees[6], // Burak Koç
content: 'Tasarımlar çok şık! Renk paleti özellikle güzel 😍',
creationTime: new Date('2024-10-17T15:00:00'),
},
{
id: 'c5',
creator: mockEmployees[7], // Elif Şahin
content: 'Dark mode opsiyonu da olacak mı?',
creationTime: new Date('2024-10-17T15:30:00'),
},
],
isOwnPost: false,
},
{
id: '4',
creator: mockEmployees[6], // Burak Koç
content:
'CI/CD pipeline güncellememiz tamamlandı! Deployment süremiz %40 azaldı. Otomasyonun gücü 💪',
creationTime: new Date('2024-10-18T08:45:00'),
media: {
type: 'video',
urls: ['https://www.w3schools.com/html/mov_bbb.mp4'],
},
likeCount: 31,
isLiked: false,
likeUsers: [],
comments: [
{
id: 'c6',
creator: mockEmployees[8], // Canan Öztürk
content: 'Harika iş! Detayları paylaşabilir misin?',
creationTime: new Date('2024-10-18T09:15:00'),
},
],
isOwnPost: false,
},
{
id: '5',
creator: mockEmployees[7], // Elif Şahin
content:
'Ekip üyelerimize yeni eğitim programımızı duyurmak istiyorum! 🎓 React, TypeScript ve Modern Web Geliştirme konularında kapsamlı bir program hazırladık.',
creationTime: new Date('2024-10-14T16:00:00'),
likeCount: 56,
isLiked: true,
likeUsers: [],
comments: [
{
id: 'c7',
creator: mockEmployees[2], // Mehmet Yılmaz
content: 'Ne zaman başlıyor?',
creationTime: new Date('2024-10-14T16:30:00'),
},
{
id: 'c8',
creator: mockEmployees[7], // Elif Şahin
content: 'Gelecek hafta başlıyoruz! Kayıt linki mail ile paylaşılacak.',
creationTime: new Date('2024-10-14T17:00:00'),
},
],
isOwnPost: false,
},
{
id: '6',
creator: mockEmployees[9], // Murat Aydın
content: 'Bugün müşteri ile harika bir toplantı yaptık! Yeni projenin detaylarını konuştuk. 🎯',
creationTime: new Date('2024-10-17T14:00:00'),
locationJson: JSON.stringify({
id: '4',
name: 'Sultanahmet Meydanı',
address: 'Sultanahmet Mahallesi, 34122 Fatih/İstanbul',
lat: 41.0058,
lng: 28.9768,
placeId: 'ChIJ7fVVZiy5yhQRzsXXXXXXXXk',
}),
likeCount: 18,
isLiked: false,
likeUsers: [],
comments: [],
isOwnPost: false,
},
]

View file

@ -232,66 +232,47 @@ export interface Visitor {
photo?: string
}
// Sosyal Duvar - Comment Interface
export interface SocialComment {
// Sosyal Duvar - Ana Interface
export interface SocialPost {
id: string
author: HrEmployee
creator: HrEmployee
content: string
locationJson?: string
media?: SocialMedia
likeCount: number
isLiked: boolean
likeUsers: HrEmployee[]
comments: SocialComment[]
isOwnPost: boolean
creationTime: Date
}
// Sosyal Duvar - Likes Interface
export interface SocialLikes {
count: number
isLiked: boolean
users: HrEmployee[]
// Sosyal Duvar - Social Media Interface
export interface SocialMedia {
id?: string
type: 'image' | 'video' | 'poll'
// Ortak alanlar
urls?: string[]
// Anket (poll) ile ilgili alanlar doğrudan burada
pollQuestion?: string
pollOptions?: SocialPollOption[]
pollTotalVotes?: number
pollEndsAt?: Date
pollUserVoteId?: string
}
// Sosyal Duvar - Poll Option Interface
export interface SocialPollOption {
id: string
text: string
votes: number
}
// Sosyal Duvar - Poll Interface
export interface SocialPoll {
question: string
options: SocialPollOption[]
totalVotes: number
endsAt: Date
userVote?: string
}
// Unified Media interface for all media-related operations
export interface SocialMedia {
id?: string
type: 'image' | 'video' | 'poll'
url?: string
urls?: string[]
file?: File
poll?: SocialPoll
}
// Sosyal Duvar - Social Location
export interface SocialLocation {
// Sosyal Duvar - Comment Interface
export interface SocialComment {
id: string
name: string
address: string
lat: number
lng: number
placeId?: string
}
// Sosyal Duvar - Ana Interface
export interface SocialPost {
id: string
author: HrEmployee
creator: HrEmployee
content: string
creationTime: Date
location?: SocialLocation
media?: SocialMedia
likes: SocialLikes
comments: SocialComment[]
isOwnPost: boolean
}

View file

@ -108,7 +108,7 @@ const IntranetDashboard: React.FC = () => {
</div>
<div className="lg:col-span-5 space-y-6">
<SocialWall />
{checkPermission('App.Intranet.SocialPost.Widget') && ( <SocialWall />) }
</div>
<div className="lg:col-span-3 space-y-6">

View file

@ -11,12 +11,12 @@ import {
} from 'react-icons/fa'
import MediaManager from './MediaManager'
import LocationPicker from './LocationPicker'
import { SocialLocation, SocialMedia } from '@/types/intranet'
import { SocialMedia } from '@/types/intranet'
interface CreatePostProps {
onCreatePost: (post: {
content: string
location?: SocialLocation
location?: string
media?: {
type: 'mixed' | 'poll'
mediaItems?: SocialMedia[]
@ -32,7 +32,7 @@ const CreatePost: React.FC<CreatePostProps> = ({ onCreatePost }) => {
const [content, setContent] = useState('')
const [mediaType, setMediaType] = useState<'media' | 'poll' | null>(null)
const [mediaItems, setMediaItems] = useState<SocialMedia[]>([])
const [location, setLocation] = useState<SocialLocation | null>(null)
const [location, setLocation] = useState<string | null>(null)
const [pollQuestion, setPollQuestion] = useState('')
const [pollOptions, setPollOptions] = useState(['', ''])
const [isExpanded, setIsExpanded] = useState(false)
@ -203,13 +203,13 @@ const CreatePost: React.FC<CreatePostProps> = ({ onCreatePost }) => {
<div key={item.id} className="relative group">
{item.type === 'image' ? (
<img
src={item.url}
src={item.urls?.[0]}
alt="Preview"
className="w-full h-24 object-cover rounded-lg"
/>
) : (
<div className="w-full h-24 bg-gray-900 rounded-lg relative">
<video src={item.url} className="w-full h-full object-cover rounded-lg" />
<video src={item.urls?.[0]} className="w-full h-full object-cover rounded-lg" />
<div className="absolute inset-0 flex items-center justify-center">
<div className="w-10 h-10 bg-black bg-opacity-50 rounded-full flex items-center justify-center">
<div className="w-0 h-0 border-t-8 border-t-transparent border-l-12 border-l-white border-b-8 border-b-transparent ml-1"></div>
@ -263,10 +263,10 @@ const CreatePost: React.FC<CreatePostProps> = ({ onCreatePost }) => {
<FaMapMarkerAlt className="w-5 h-5 text-blue-600 mt-0.5 flex-shrink-0" />
<div className="flex-1 min-w-0">
<h3 className="font-semibold text-gray-900 dark:text-gray-100 mb-1">
{location.name}
{JSON.parse(location).name}
</h3>
<p className="text-sm text-gray-600 dark:text-gray-400 line-clamp-2">
{location.address}
{JSON.parse(location).address}
</p>
</div>
</div>

View file

@ -1,9 +1,17 @@
import React from 'react'
import { FaExternalLinkAlt, FaMapMarkerAlt } from 'react-icons/fa'
import { SocialLocation } from '@/types/intranet'
interface LocationData {
id: string
name: string
address: string
lat: number
lng: number
placeId?: string
}
interface LocationMapProps {
location: SocialLocation
location: string // JSON string
className?: string
showDirections?: boolean
}
@ -13,14 +21,16 @@ const LocationMap: React.FC<LocationMapProps> = ({
className = '',
showDirections = true
}) => {
const locationData: LocationData = JSON.parse(location)
const handleOpenGoogleMaps = () => {
const url = `https://www.google.com/maps/search/?api=1&query=${location.lat},${location.lng}&query_place_id=${location.placeId || ''}`
const url = `https://www.google.com/maps/search/?api=1&query=${locationData.lat},${locationData.lng}&query_place_id=${locationData.placeId || ''}`
window.open(url, '_blank')
}
// Google Maps Static API URL (gerçek uygulamada API key eklenecek)
const getMapImageUrl = () => {
const { lat, lng } = location
const { lat, lng } = locationData
const zoom = 15
const size = '600x300'
const marker = `color:red|${lat},${lng}`
@ -39,7 +49,7 @@ const LocationMap: React.FC<LocationMapProps> = ({
<div className="relative w-full h-64 group">
{/* OpenStreetMap iframe for demo */}
<iframe
title={`Map of ${location.name}`}
title={`Map of ${locationData.name}`}
src={getMapImageUrl()}
className="w-full h-full border-0"
allowFullScreen
@ -54,9 +64,9 @@ const LocationMap: React.FC<LocationMapProps> = ({
<div className="flex items-start gap-2">
<FaMapMarkerAlt className="w-5 h-5 mt-0.5 flex-shrink-0" />
<div className="flex-1 min-w-0">
<h3 className="font-bold text-lg mb-1 drop-shadow-lg">{location.name}</h3>
<h3 className="font-bold text-lg mb-1 drop-shadow-lg">{locationData.name}</h3>
<p className="text-sm text-white/90 drop-shadow-md line-clamp-2">
{location.address}
{locationData.address}
</p>
</div>
</div>

View file

@ -2,13 +2,21 @@ import React, { useState, useEffect, useRef } from 'react'
import { motion } from 'framer-motion'
import { FaTimes, FaSearch, FaMapMarkerAlt } from 'react-icons/fa'
import classNames from 'classnames'
import { SocialLocation } from '@/types/intranet'
interface LocationPickerProps {
onSelect: (location: SocialLocation) => void
onSelect: (location: string) => void
onClose: () => void
}
interface LocationData {
id: string
name: string
address: string
lat: number
lng: number
placeId?: string
}
// Google Maps API key - .env dosyasından alınmalı
const GOOGLE_API_KEY = import.meta.env.VITE_GOOGLE_MAPS_API_KEY || ''
@ -21,8 +29,8 @@ declare global {
const LocationPicker: React.FC<LocationPickerProps> = ({ onSelect, onClose }) => {
const [searchQuery, setSearchQuery] = useState('')
const [locations, setLocations] = useState<SocialLocation[]>([])
const [selectedLocation, setSelectedLocation] = useState<SocialLocation | null>(null)
const [locations, setLocations] = useState<LocationData[]>([])
const [selectedLocation, setSelectedLocation] = useState<LocationData | null>(null)
const [isLoading, setIsLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
const [isGoogleLoaded, setIsGoogleLoaded] = useState(false)
@ -146,7 +154,7 @@ const LocationPicker: React.FC<LocationPickerProps> = ({ onSelect, onClose }) =>
}
// Her bir prediction için detaylı bilgi al
const detailedLocations: SocialLocation[] = []
const detailedLocations: LocationData[] = []
let completed = 0
predictions.forEach((prediction: any) => {
@ -193,13 +201,13 @@ const LocationPicker: React.FC<LocationPickerProps> = ({ onSelect, onClose }) =>
}
}, [searchQuery, isGoogleLoaded])
const handleSelect = (location: SocialLocation) => {
const handleSelect = (location: LocationData) => {
setSelectedLocation(location)
}
const handleConfirm = () => {
if (selectedLocation) {
onSelect(selectedLocation)
onSelect(JSON.stringify(selectedLocation))
onClose()
}
}

View file

@ -21,13 +21,13 @@ const MediaLightbox: React.FC<MediaLightboxProps> = ({
startIndex = 0
}) => {
const slides = React.useMemo(() => {
if (media.type === 'video' && media.url) {
if (media.type === 'video' && media.urls && media.urls.length > 0) {
return [
{
type: 'video' as const,
sources: [
{
src: media.url,
src: media.urls[0],
type: 'video/mp4'
}
]
@ -35,7 +35,7 @@ const MediaLightbox: React.FC<MediaLightboxProps> = ({
]
}
const urls = media.urls || (media.url ? [media.url] : [])
const urls = media.urls || []
return urls.map((url) => ({
src: url
}))

View file

@ -22,7 +22,7 @@ const MediaManager: React.FC<MediaManagerProps> = ({ media, onChange, onClose })
const newMedia: SocialMedia[] = Array.from(files).map((file) => ({
id: Math.random().toString(36).substr(2, 9),
type: file.type.startsWith('video/') ? 'video' : 'image',
url: URL.createObjectURL(file),
urls: [URL.createObjectURL(file)],
file
}))
@ -36,7 +36,7 @@ const MediaManager: React.FC<MediaManagerProps> = ({ media, onChange, onClose })
const newMedia: SocialMedia = {
id: Math.random().toString(36).substr(2, 9),
type: mediaType,
url: urlInput
urls: [urlInput]
}
onChange([...media, newMedia])
@ -184,13 +184,13 @@ const MediaManager: React.FC<MediaManagerProps> = ({ media, onChange, onClose })
<div key={item.id} className="relative group">
{item.type === 'image' ? (
<img
src={item.url}
src={item.urls?.[0]}
alt="Media preview"
className="w-full h-24 object-cover rounded-lg"
/>
) : (
<div className="w-full h-24 bg-gray-900 rounded-lg flex items-center justify-center">
<video src={item.url} className="w-full h-full object-cover rounded-lg" />
<video src={item.urls?.[0]} className="w-full h-full object-cover rounded-lg" />
<div className="absolute inset-0 flex items-center justify-center">
<div className="w-10 h-10 bg-black bg-opacity-50 rounded-full flex items-center justify-center">
<div className="w-0 h-0 border-t-8 border-t-transparent border-l-12 border-l-white border-b-8 border-b-transparent ml-1"></div>

View file

@ -145,76 +145,53 @@ const PostItem: React.FC<PostItemProps> = ({ post, onLike, onComment, onDelete,
/>
</>
)
} else if (post.media.url) {
}
break
case 'video':
if (post.media.urls && post.media.urls.length > 0) {
return (
<>
<div
className="mt-3 rounded-lg overflow-hidden cursor-pointer"
className="mt-3 rounded-lg overflow-hidden cursor-pointer relative group"
onClick={() => setLightboxOpen(true)}
>
<img
src={post.media.url}
alt="Post"
className="w-full object-cover max-h-96 hover:opacity-90 transition-opacity"
<video
ref={videoRef}
src={post.media.urls[0]}
className="w-full max-h-96 object-cover"
controls
playsInline
muted
loop
/>
</div>
<MediaLightbox
isOpen={lightboxOpen}
onClose={() => setLightboxOpen(false)}
media={{ type: 'image', url: post.media.url }}
media={{ type: 'video', urls: [post.media.urls[0]] }}
/>
</>
)
}
break
case 'video':
return (
<>
<div
className="mt-3 rounded-lg overflow-hidden cursor-pointer relative group"
onClick={() => setLightboxOpen(true)}
>
<video
ref={videoRef}
className="w-full max-h-96"
src={post.media.url}
loop
muted
playsInline
>
Tarayıcınız video etiketini desteklemiyor.
</video>
<div className="absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-30 transition-all flex items-center justify-center">
<div className="w-16 h-16 bg-white bg-opacity-90 rounded-full flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity">
<div className="w-0 h-0 border-t-10 border-t-transparent border-l-16 border-l-blue-600 border-b-10 border-b-transparent ml-1"></div>
</div>
</div>
</div>
<MediaLightbox
isOpen={lightboxOpen}
onClose={() => setLightboxOpen(false)}
media={{ type: 'video', url: post.media.url || '' }}
/>
</>
)
case 'poll':
if (post.media.poll) {
const poll = post.media.poll
const isExpired = new Date() > poll.endsAt
const hasVoted = !!poll.userVote
if (post.media.pollQuestion && post.media.pollOptions) {
const isExpired = post.media.pollEndsAt ? new Date() > post.media.pollEndsAt : false
const hasVoted = !!post.media.pollUserVoteId
const totalVotes = post.media.pollTotalVotes || 0
const pollUserVoteId = post.media.pollUserVoteId
return (
<div className="mt-3 p-4 bg-gray-50 dark:bg-gray-700 rounded-lg">
<h4 className="font-medium text-gray-900 dark:text-gray-100 mb-3">
{poll.question}
{post.media.pollQuestion}
</h4>
<div className="space-y-2">
{poll.options.map((option) => {
const percentage =
poll.totalVotes > 0 ? (option.votes / poll.totalVotes) * 100 : 0
const isSelected = poll.userVote === option.id
{post.media.pollOptions.map((option) => {
const percentage = totalVotes > 0 ? (option.votes / totalVotes) * 100 : 0
const isSelected = pollUserVoteId === option.id
return (
<button
@ -254,7 +231,7 @@ const PostItem: React.FC<PostItemProps> = ({ post, onLike, onComment, onDelete,
})}
</div>
<div className="mt-3 text-sm text-gray-600 dark:text-gray-400">
{poll.totalVotes} oy {isExpired ? 'Sona erdi' : dayjs(poll.endsAt).fromNow() + ' bitiyor'}
{totalVotes} oy {isExpired ? 'Sona erdi' : post.media.pollEndsAt ? dayjs(post.media.pollEndsAt).fromNow() + ' bitiyor' : ''}
</div>
</div>
)
@ -281,22 +258,22 @@ const PostItem: React.FC<PostItemProps> = ({ post, onLike, onComment, onDelete,
onMouseLeave={() => setShowUserCard(false)}
>
<img
src={post.author.avatar || 'https://i.pravatar.cc/150?img=1'}
alt={post.author.fullName}
src={post.creator.avatar || 'https://i.pravatar.cc/150?img=1'}
alt={post.creator.fullName}
className="w-12 h-12 rounded-full object-cover cursor-pointer ring-2 ring-transparent hover:ring-blue-500 transition-all"
/>
<AnimatePresence>
{showUserCard && (
<UserProfileCard
user={{
id: post.author.id,
name: post.author.fullName,
avatar: post.author.avatar || 'https://i.pravatar.cc/150?img=1',
title: post.author.jobPosition?.name || 'Çalışan',
email: post.author.email,
phone: post.author.phone,
department: post.author.department?.name,
location: post.author.workLocation
id: post.creator.id,
name: post.creator.fullName,
avatar: post.creator.avatar || 'https://i.pravatar.cc/150?img=1',
title: post.creator.jobPosition?.name || 'Çalışan',
email: post.creator.email,
phone: post.creator.phone,
department: post.creator.department?.name,
location: post.creator.workLocation
}}
position="bottom"
/>
@ -305,10 +282,10 @@ const PostItem: React.FC<PostItemProps> = ({ post, onLike, onComment, onDelete,
</div>
<div>
<h3 className="font-semibold text-gray-900 dark:text-gray-100">
{post.author.fullName}
{post.creator.fullName}
</h3>
<p className="text-sm text-gray-600 dark:text-gray-400">
{post.author.jobPosition?.name || 'Çalışan'} {dayjs(post.creationTime).fromNow()}
{post.creator.jobPosition?.name || 'Çalışan'} {dayjs(post.creationTime).fromNow()}
</p>
</div>
</div>
@ -329,9 +306,9 @@ const PostItem: React.FC<PostItemProps> = ({ post, onLike, onComment, onDelete,
{renderMedia()}
{/* Location */}
{post.location && (
{post.locationJson && (
<div className="mt-3">
<LocationMap location={post.location} />
<LocationMap location={post.locationJson} />
</div>
)}
</div>
@ -342,17 +319,17 @@ const PostItem: React.FC<PostItemProps> = ({ post, onLike, onComment, onDelete,
onClick={() => onLike(post.id)}
className={classNames(
'flex items-center gap-2 transition-colors',
post.likes.isLiked
post.isLiked
? 'text-red-600 hover:text-red-700'
: 'text-gray-600 dark:text-gray-400 hover:text-red-600'
)}
>
{post.likes.isLiked ? (
{post.isLiked ? (
<FaHeart className="w-5 h-5" />
) : (
<FaRegHeart className="w-5 h-5" />
)}
<span className="text-sm font-medium">{post.likes.count}</span>
<span className="text-sm font-medium">{post.likeCount}</span>
</button>
<button
@ -403,18 +380,18 @@ const PostItem: React.FC<PostItemProps> = ({ post, onLike, onComment, onDelete,
onMouseLeave={() => setHoveredCommentAuthor(null)}
>
<img
src={comment.author.avatar || 'https://i.pravatar.cc/150?img=1'}
alt={comment.author.fullName}
src={comment.creator.avatar || 'https://i.pravatar.cc/150?img=1'}
alt={comment.creator.fullName}
className="w-8 h-8 rounded-full object-cover cursor-pointer ring-2 ring-transparent hover:ring-blue-500 transition-all"
/>
<AnimatePresence>
{hoveredCommentAuthor === comment.id && (
<UserProfileCard
user={{
id: comment.author.id,
name: comment.author.fullName,
avatar: comment.author.avatar || 'https://i.pravatar.cc/150?img=1',
title: comment.author.jobPosition?.name || 'Çalışan'
id: comment.creator.id,
name: comment.creator.fullName,
avatar: comment.creator.avatar || 'https://i.pravatar.cc/150?img=1',
title: comment.creator.jobPosition?.name || 'Çalışan'
}}
position="bottom"
/>
@ -424,7 +401,7 @@ const PostItem: React.FC<PostItemProps> = ({ post, onLike, onComment, onDelete,
<div className="flex-1">
<div className="bg-gray-100 dark:bg-gray-700 rounded-lg px-4 py-2">
<h4 className="font-semibold text-sm text-gray-900 dark:text-gray-100">
{comment.author.fullName}
{comment.creator.fullName}
</h4>
<p className="text-sm text-gray-800 dark:text-gray-200">{comment.content}</p>
</div>

View file

@ -3,7 +3,7 @@ import { AnimatePresence } from 'framer-motion'
import PostItem from './PostItem'
import { SocialMedia } from '@/types/intranet'
import CreatePost from './CreatePost'
import { SocialLocation, SocialPost } from '@/types/intranet'
import { SocialPost } from '@/types/intranet'
import { HrEmployee } from '@/types/hr'
import { mockSocialPosts } from '@/mocks/mockIntranet'
import { mockEmployees } from '@/mocks/mockEmployees'
@ -17,7 +17,7 @@ const SocialWall: React.FC = () => {
const handleCreatePost = (postData: {
content: string
location?: SocialLocation
location?: string
media?: {
type: 'mixed' | 'poll'
mediaItems?: SocialMedia[]
@ -38,49 +38,45 @@ const SocialWall: React.FC = () => {
if (images.length > 0 && videos.length === 0) {
mediaForPost = {
type: 'image' as const,
urls: images.map(i => i.url).filter(url => url !== undefined) as string[]
urls: images.map(i => i.urls?.[0]).filter(url => url !== undefined) as string[]
}
} else if (videos.length > 0 && images.length === 0) {
mediaForPost = {
type: 'video' as const,
url: videos[0].url
urls: videos[0].urls || []
}
} else if (images.length > 0 || videos.length > 0) {
// Mixed media - use first image for now
mediaForPost = {
type: 'image' as const,
urls: images.map(i => i.url).filter(url => url !== undefined) as string[]
urls: images.map(i => i.urls?.[0]).filter(url => url !== undefined) as string[]
}
}
} else if (postData.media.type === 'poll' && postData.media.poll) {
mediaForPost = {
type: 'poll' as const,
poll: {
question: postData.media.poll.question,
options: postData.media.poll.options.map((opt, index) => ({
id: `opt-${index}`,
text: opt.text,
votes: 0
})),
totalVotes: 0,
endsAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)
}
pollQuestion: postData.media.poll.question,
pollOptions: postData.media.poll.options.map((opt, index) => ({
id: `opt-${index}`,
text: opt.text,
votes: 0
})),
pollTotalVotes: 0,
pollEndsAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)
}
}
}
const newPost: SocialPost = {
id: Date.now().toString(),
author: currentUserAuthor,
creator: currentUserAuthor,
content: postData.content,
creationTime: new Date(),
media: mediaForPost,
location: postData.location,
likes: {
count: 0,
isLiked: false,
users: []
},
locationJson: postData.location,
likeCount: 0,
isLiked: false,
likeUsers: [],
comments: [],
isOwnPost: true
}
@ -94,11 +90,8 @@ const SocialWall: React.FC = () => {
if (post.id === postId) {
return {
...post,
likes: {
...post.likes,
count: post.likes.isLiked ? post.likes.count - 1 : post.likes.count + 1,
isLiked: !post.likes.isLiked
}
likeCount: post.isLiked ? post.likeCount - 1 : post.likeCount + 1,
isLiked: !post.isLiked
}
}
return post
@ -114,7 +107,7 @@ const SocialWall: React.FC = () => {
const newComment = {
id: Date.now().toString(),
author: commentAuthor,
creator: commentAuthor,
content,
creationTime: new Date()
}
@ -137,11 +130,9 @@ const SocialWall: React.FC = () => {
const handleVote = (postId: string, optionId: string) => {
setPosts(
posts.map((post) => {
if (post.id === postId && post.media?.type === 'poll' && post.media.poll) {
const poll = post.media.poll
if (post.id === postId && post.media?.type === 'poll' && post.media.pollOptions) {
// If user already voted, don't allow voting again
if (poll.userVote) {
if (post.media.pollUserVoteId) {
return post
}
@ -149,14 +140,11 @@ const SocialWall: React.FC = () => {
...post,
media: {
...post.media,
poll: {
...poll,
options: poll.options.map((opt) =>
opt.id === optionId ? { ...opt, votes: opt.votes + 1 } : opt
),
totalVotes: poll.totalVotes + 1,
userVote: optionId
}
pollOptions: post.media.pollOptions.map((opt) =>
opt.id === optionId ? { ...opt, votes: opt.votes + 1 } : opt
),
pollTotalVotes: (post.media.pollTotalVotes || 0) + 1,
pollUserVoteId: optionId
}
}
}

View file

@ -56,7 +56,7 @@ const MealWeeklyMenu: React.FC = () => {
</div>
<div className="flex flex-wrap gap-2">
{menu.meals[0]?.items.map((item, idx) => (
<Badge key={idx} content={item} className='bg-red-500' />
<Badge key={idx} content={item} className='p-1 bg-red-500' />
))}
</div>
</div>

View file

@ -12,7 +12,7 @@ const TodayBirthdays: React.FC = () => {
return (
<div className="bg-gradient-to-br from-pink-50 to-purple-50 dark:from-pink-900/20 dark:to-purple-900/20 rounded-lg shadow-sm border border-pink-200 dark:border-pink-800">
<div className="p-6 border-b border-pink-200 dark:border-pink-700">
<div className="p-4 border-b border-pink-200 dark:border-pink-700">
<h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2">
🎂 Bugün Doğanlar
</h2>