Portfolio.Web
1.0.0.0
.NET, Blazor, WPF와 서비스 운영 경험을 프로젝트·이력·기술 스택 단위로 보여주는 개발자 포트폴리오입니다.
Toggle main menu visibility
로딩중...
검색중...
일치하는것 없음
PortfolioPublicViewModel.cs
이 파일의 문서화 페이지로 가기
1
using
PortfolioApp.Models
;
2
using
PortfolioApp.Services
;
3
4
namespace
PortfolioApp.ViewModels
;
5
14
public
class
PortfolioPublicViewModel
15
{
24
private
readonly
IPortfolioTenantStore
_tenants
;
33
private
readonly
IProjectStore
_projects
;
42
private
readonly
IResumeStore
_resumes
;
51
private
readonly
IContactStore
_contacts
;
60
private
readonly
IMediaService
_media
;
61
70
public
PortfolioConfig
?
Config
{
get
;
private
set
; }
79
public
List<ProjectItem>
Projects
{
get
;
private
set
; } = [];
88
public
ResumeInfo
Resume
{
get
;
private
set
; } =
new
();
97
public
bool
HasLoaded
{
get
;
private
set
; }
106
public
string
StatusMessage
{
get
;
set
; } =
""
;
107
108
// 연락처 폼
117
public
string
ContactName
{
get
;
set
; } =
""
;
126
public
string
ContactEmail
{
get
;
set
; } =
""
;
135
public
string
ContactMessage
{
get
;
set
; } =
""
;
136
137
// 필터/검색
146
public
string
Query
{
get
;
set
; } =
""
;
155
public
string
SelectedTag
{
get
;
set
; } =
""
;
164
public
string
SelectedCategory
{
get
;
set
; } =
""
;
165
174
public
List<ProjectItem>
Personal
=>
FilteredProjects
.Where(p => p.Category ==
ProjectCategory
.Personal).ToList();
183
public
List<ProjectItem>
Work
=>
FilteredProjects
.Where(p => p.Category ==
ProjectCategory
.Work).ToList();
192
public
List<ProjectItem>
Public
=>
FilteredProjects
.Where(p => p.Category ==
ProjectCategory
.Public).ToList();
193
202
public
IEnumerable<string>
AllTags
=>
Projects
203
.SelectMany(p => p.Tags)
204
.Distinct()
205
.OrderBy(t => t);
206
215
private
List<ProjectItem>
FilteredProjects
216
{
217
get
218
{
219
var q =
Projects
.AsEnumerable();
220
if
(!
string
.IsNullOrWhiteSpace(
Query
))
221
{
222
var lq =
Query
.ToLowerInvariant();
223
q = q.Where(p => p.Title.ToLower().Contains(lq)
224
|| p.Description.ToLower().Contains(lq)
225
|| p.Tags.Any(t => t.ToLower().Contains(lq)));
226
}
227
if
(!
string
.IsNullOrWhiteSpace(
SelectedTag
))
228
q = q.Where(p => p.Tags.Contains(
SelectedTag
));
229
if
(!
string
.IsNullOrWhiteSpace(
SelectedCategory
) &&
230
Enum.TryParse<
ProjectCategory
>(
SelectedCategory
, out var cat))
231
q = q.Where(p => p.Category == cat);
232
return
q.ToList();
233
}
234
}
235
284
public
PortfolioPublicViewModel
(
285
IPortfolioTenantStore
tenants,
286
IProjectStore
projects,
287
IResumeStore
resumes,
288
IContactStore
contacts,
289
IMediaService
media)
290
{
291
_tenants
= tenants;
292
_projects
= projects;
293
_resumes
= resumes;
294
_contacts
= contacts;
295
_media
= media;
296
}
297
322
public
async Task
LoadAsync
(
string
slug)
323
{
324
HasLoaded
=
false
;
325
Config
=
null
;
326
Projects
= [];
327
Resume
=
new
();
328
329
Config
= await
_tenants
.GetAsync(slug);
330
if
(
Config
==
null
)
331
{
332
HasLoaded
=
true
;
333
return
;
334
}
335
336
Projects
= await
_projects
.GetAllAsync(slug);
337
Resume
= await
_resumes
.GetAsync(slug);
338
// 기존 데이터 마이그레이션: ImageFileName → WorkImages (표시 전용, 저장 안 함)
339
foreach
(var p
in
Projects
.Where(p =>
340
!
string
.IsNullOrWhiteSpace(p.ImageFileName) && p.WorkImages.Length == 0))
341
p.WorkImages = [p.ImageFileName!];
342
343
HasLoaded
=
true
;
344
}
345
386
public
string
GetMediaUrl
(
string
slug,
string
projectId,
string
fileName) =>
387
_media
.GetMediaUrl(slug, projectId, fileName);
388
429
public
string
GetImageUrl
(
string
slug,
string
projectId,
string
fileName) =>
430
IsExternalUrl
(fileName) ? fileName :
_media
.GetMediaUrl(slug, projectId, fileName);
431
472
public
string
GetVideoUrl
(
string
slug,
string
projectId,
string
fileName) =>
473
IsExternalUrl
(fileName) ? fileName :
_media
.GetMediaUrl(slug, projectId, fileName);
474
499
public
static
bool
IsYouTube
(
string
url) =>
500
url.Contains(
"youtube.com"
) || url.Contains(
"youtu.be"
);
501
526
public
static
string
GetYouTubeEmbedUrl
(
string
url)
527
{
528
// youtu.be/ID 또는 youtube.com/watch?v=ID → /embed/ID
529
var
id
=
""
;
530
if
(url.Contains(
"youtu.be/"
))
531
id
= url.Split(
"youtu.be/"
)[1].Split(
'?'
)[0].Split(
'&'
)[0];
532
else
if
(url.Contains(
"v="
))
533
id
= url.Split(
"v="
)[1].Split(
'&'
)[0].Split(
'?'
)[0];
534
return
string
.IsNullOrWhiteSpace(
id
) ? url : $
"https://www.youtube.com/embed/{id}"
;
535
}
536
561
private
static
bool
IsExternalUrl
(
string
url) =>
562
url.StartsWith(
'/'
) || url.StartsWith(
"http://"
) || url.StartsWith(
"https://"
);
563
596
public
string
GetProfileImageUrl
(
string
slug,
string
fileName) =>
597
_media
.GetProfileImageUrl(slug, fileName);
598
623
public
async Task<bool>
SendContactAsync
(
string
slug)
624
{
625
StatusMessage
=
""
;
626
if
(
string
.IsNullOrWhiteSpace(
ContactName
)) {
StatusMessage
=
"❌ 이름을 입력하세요."
;
return
false
; }
627
if
(
string
.IsNullOrWhiteSpace(
ContactMessage
)) {
StatusMessage
=
"❌ 메시지를 입력하세요."
;
return
false
; }
628
629
var msg =
new
ContactMessage
630
{
631
SenderName =
ContactName
.Trim(),
632
Email =
ContactEmail
.Trim(),
633
Message =
ContactMessage
.Trim(),
634
SentAt = DateTime.Now,
635
};
636
await
_contacts
.SaveAsync(slug, msg);
637
ContactName
=
ContactEmail
=
ContactMessage
=
""
;
638
StatusMessage
=
"✅ 메시지가 전송되었습니다."
;
639
return
true
;
640
}
641
}
PortfolioApp.Models
Definition
ContactMessage.cs:1
PortfolioApp.Models.ProjectCategory
ProjectCategory
Definition
ProjectItem.cs:12
PortfolioApp.Services
Definition
GhostAccountCleanupService.cs:4
PortfolioApp.ViewModels
Definition
PortfolioAdminViewModel.cs:7
PortfolioApp.Models.PortfolioConfig
Definition
PortfolioConfig.cs:12
PortfolioApp.Models.ResumeInfo
Definition
ResumeInfo.cs:12
PortfolioApp.Services.IContactStore
Definition
IContactStore.cs:14
PortfolioApp.Services.IMediaService
Definition
IMediaService.cs:14
PortfolioApp.Services.IPortfolioTenantStore
Definition
IPortfolioTenantStore.cs:14
PortfolioApp.Services.IProjectStore
Definition
IProjectStore.cs:14
PortfolioApp.Services.IResumeStore
Definition
IResumeStore.cs:14
PortfolioApp.ViewModels.PortfolioPublicViewModel.StatusMessage
string StatusMessage
Definition
PortfolioPublicViewModel.cs:106
PortfolioApp.ViewModels.PortfolioPublicViewModel.AllTags
IEnumerable< string > AllTags
Definition
PortfolioPublicViewModel.cs:202
PortfolioApp.ViewModels.PortfolioPublicViewModel.GetYouTubeEmbedUrl
static string GetYouTubeEmbedUrl(string url)
Definition
PortfolioPublicViewModel.cs:526
PortfolioApp.ViewModels.PortfolioPublicViewModel.SelectedCategory
string SelectedCategory
Definition
PortfolioPublicViewModel.cs:164
PortfolioApp.ViewModels.PortfolioPublicViewModel.ContactName
string ContactName
Definition
PortfolioPublicViewModel.cs:117
PortfolioApp.ViewModels.PortfolioPublicViewModel.FilteredProjects
List< ProjectItem > FilteredProjects
Definition
PortfolioPublicViewModel.cs:216
PortfolioApp.ViewModels.PortfolioPublicViewModel.SelectedTag
string SelectedTag
Definition
PortfolioPublicViewModel.cs:155
PortfolioApp.ViewModels.PortfolioPublicViewModel._contacts
readonly IContactStore _contacts
Definition
PortfolioPublicViewModel.cs:51
PortfolioApp.ViewModels.PortfolioPublicViewModel.Config
PortfolioConfig? Config
Definition
PortfolioPublicViewModel.cs:70
PortfolioApp.ViewModels.PortfolioPublicViewModel.ContactEmail
string ContactEmail
Definition
PortfolioPublicViewModel.cs:126
PortfolioApp.ViewModels.PortfolioPublicViewModel.LoadAsync
async Task LoadAsync(string slug)
Definition
PortfolioPublicViewModel.cs:322
PortfolioApp.ViewModels.PortfolioPublicViewModel.Public
List< ProjectItem > Public
Definition
PortfolioPublicViewModel.cs:192
PortfolioApp.ViewModels.PortfolioPublicViewModel.ContactMessage
string ContactMessage
Definition
PortfolioPublicViewModel.cs:135
PortfolioApp.ViewModels.PortfolioPublicViewModel.Personal
List< ProjectItem > Personal
Definition
PortfolioPublicViewModel.cs:174
PortfolioApp.ViewModels.PortfolioPublicViewModel.Resume
ResumeInfo Resume
Definition
PortfolioPublicViewModel.cs:88
PortfolioApp.ViewModels.PortfolioPublicViewModel.IsExternalUrl
static bool IsExternalUrl(string url)
Definition
PortfolioPublicViewModel.cs:561
PortfolioApp.ViewModels.PortfolioPublicViewModel.GetVideoUrl
string GetVideoUrl(string slug, string projectId, string fileName)
Definition
PortfolioPublicViewModel.cs:472
PortfolioApp.ViewModels.PortfolioPublicViewModel.HasLoaded
bool HasLoaded
Definition
PortfolioPublicViewModel.cs:97
PortfolioApp.ViewModels.PortfolioPublicViewModel.PortfolioPublicViewModel
PortfolioPublicViewModel(IPortfolioTenantStore tenants, IProjectStore projects, IResumeStore resumes, IContactStore contacts, IMediaService media)
Definition
PortfolioPublicViewModel.cs:284
PortfolioApp.ViewModels.PortfolioPublicViewModel._media
readonly IMediaService _media
Definition
PortfolioPublicViewModel.cs:60
PortfolioApp.ViewModels.PortfolioPublicViewModel.GetImageUrl
string GetImageUrl(string slug, string projectId, string fileName)
Definition
PortfolioPublicViewModel.cs:429
PortfolioApp.ViewModels.PortfolioPublicViewModel.GetMediaUrl
string GetMediaUrl(string slug, string projectId, string fileName)
Definition
PortfolioPublicViewModel.cs:386
PortfolioApp.ViewModels.PortfolioPublicViewModel.IsYouTube
static bool IsYouTube(string url)
Definition
PortfolioPublicViewModel.cs:499
PortfolioApp.ViewModels.PortfolioPublicViewModel.Query
string Query
Definition
PortfolioPublicViewModel.cs:146
PortfolioApp.ViewModels.PortfolioPublicViewModel._tenants
readonly IPortfolioTenantStore _tenants
Definition
PortfolioPublicViewModel.cs:24
PortfolioApp.ViewModels.PortfolioPublicViewModel.Projects
List< ProjectItem > Projects
Definition
PortfolioPublicViewModel.cs:79
PortfolioApp.ViewModels.PortfolioPublicViewModel._projects
readonly IProjectStore _projects
Definition
PortfolioPublicViewModel.cs:33
PortfolioApp.ViewModels.PortfolioPublicViewModel.GetProfileImageUrl
string GetProfileImageUrl(string slug, string fileName)
Definition
PortfolioPublicViewModel.cs:596
PortfolioApp.ViewModels.PortfolioPublicViewModel.Work
List< ProjectItem > Work
Definition
PortfolioPublicViewModel.cs:183
PortfolioApp.ViewModels.PortfolioPublicViewModel._resumes
readonly IResumeStore _resumes
Definition
PortfolioPublicViewModel.cs:42
PortfolioApp.ViewModels.PortfolioPublicViewModel.SendContactAsync
async Task< bool > SendContactAsync(string slug)
Definition
PortfolioPublicViewModel.cs:623
ViewModels
PortfolioPublicViewModel.cs
다음에 의해 생성됨 :
1.17.0