Log on works; WIP on dashboard
This commit is contained in:
parent
65e23a5b03
commit
a424aee540
1
src/JobsJobsJobs/Api/.gitignore
vendored
Normal file
1
src/JobsJobsJobs/Api/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
wwwroot
|
|
@ -20,6 +20,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Giraffe" Version="5.0.0" />
|
<PackageReference Include="Giraffe" Version="5.0.0" />
|
||||||
<PackageReference Include="Microsoft.FSharpLu.Json" Version="0.11.7" />
|
<PackageReference Include="Microsoft.FSharpLu.Json" Version="0.11.7" />
|
||||||
|
<PackageReference Include="NodaTime.Serialization.JsonNet" Version="3.0.0" />
|
||||||
<PackageReference Include="Polly" Version="7.2.2" />
|
<PackageReference Include="Polly" Version="7.2.2" />
|
||||||
<PackageReference Include="RethinkDb.Driver" Version="2.3.150" />
|
<PackageReference Include="RethinkDb.Driver" Version="2.3.150" />
|
||||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.11.1" />
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.11.1" />
|
||||||
|
|
|
@ -12,9 +12,12 @@ open Giraffe.EndpointRouting
|
||||||
/// Configure the ASP.NET Core pipeline to use Giraffe
|
/// Configure the ASP.NET Core pipeline to use Giraffe
|
||||||
let configureApp (app : IApplicationBuilder) =
|
let configureApp (app : IApplicationBuilder) =
|
||||||
app
|
app
|
||||||
.UseCors(fun p -> p.AllowAnyOrigin() |> ignore)
|
.UseCors(fun p -> p.AllowAnyOrigin().AllowAnyHeader() |> ignore)
|
||||||
|
.UseStaticFiles()
|
||||||
.UseRouting()
|
.UseRouting()
|
||||||
.UseEndpoints(fun e -> e.MapGiraffeEndpoints Handlers.allEndpoints)
|
.UseEndpoints(fun e ->
|
||||||
|
e.MapGiraffeEndpoints Handlers.allEndpoints
|
||||||
|
e.MapFallbackToFile "index.html" |> ignore)
|
||||||
|> ignore
|
|> ignore
|
||||||
|
|
||||||
open NodaTime
|
open NodaTime
|
||||||
|
|
|
@ -106,11 +106,14 @@ module Startup =
|
||||||
|
|
||||||
open Microsoft.Extensions.Configuration
|
open Microsoft.Extensions.Configuration
|
||||||
open Microsoft.Extensions.Logging
|
open Microsoft.Extensions.Logging
|
||||||
|
open NodaTime
|
||||||
|
open NodaTime.Serialization.JsonNet
|
||||||
|
|
||||||
/// Create a RethinkDB connection
|
/// Create a RethinkDB connection
|
||||||
let createConnection (cfg : IConfigurationSection) (log : ILogger) =
|
let createConnection (cfg : IConfigurationSection) (log : ILogger) =
|
||||||
|
|
||||||
// Add all required JSON converters
|
// Add all required JSON converters
|
||||||
|
Converter.Serializer.ConfigureForNodaTime DateTimeZoneProviders.Tzdb |> ignore
|
||||||
Converters.all ()
|
Converters.all ()
|
||||||
|> List.iter Converter.Serializer.Converters.Add
|
|> List.iter Converter.Serializer.Converters.Add
|
||||||
// Read the configuration and create a connection
|
// Read the configuration and create a connection
|
||||||
|
|
|
@ -7,6 +7,7 @@ open JobsJobsJobs.Domain
|
||||||
open JobsJobsJobs.Domain.SharedTypes
|
open JobsJobsJobs.Domain.SharedTypes
|
||||||
open JobsJobsJobs.Domain.Types
|
open JobsJobsJobs.Domain.Types
|
||||||
open Microsoft.AspNetCore.Http
|
open Microsoft.AspNetCore.Http
|
||||||
|
open Microsoft.Extensions.Logging
|
||||||
|
|
||||||
/// Handler to return the files required for the Vue client app
|
/// Handler to return the files required for the Vue client app
|
||||||
module Vue =
|
module Vue =
|
||||||
|
@ -19,15 +20,20 @@ module Vue =
|
||||||
module Error =
|
module Error =
|
||||||
|
|
||||||
open System.Threading.Tasks
|
open System.Threading.Tasks
|
||||||
|
open Microsoft.Extensions.Logging
|
||||||
|
|
||||||
/// Handler that will return a status code 404 and the text "Not Found"
|
/// Handler that will return a status code 404 and the text "Not Found"
|
||||||
let notFound : HttpHandler =
|
let notFound : HttpHandler =
|
||||||
fun next ctx -> task {
|
fun next ctx -> task {
|
||||||
|
let fac = ctx.GetService<ILoggerFactory>()
|
||||||
|
let log = fac.CreateLogger("Handler")
|
||||||
match [ "GET"; "HEAD" ] |> List.contains ctx.Request.Method with
|
match [ "GET"; "HEAD" ] |> List.contains ctx.Request.Method with
|
||||||
| true ->
|
| true ->
|
||||||
|
log.LogInformation "Returning Vue app"
|
||||||
// TODO: check for valid URL prefixes
|
// TODO: check for valid URL prefixes
|
||||||
return! Vue.app next ctx
|
return! Vue.app next ctx
|
||||||
| false ->
|
| false ->
|
||||||
|
log.LogInformation "Returning 404"
|
||||||
return! RequestErrors.NOT_FOUND $"The URL {string ctx.Request.Path} was not recognized as a valid URL" next
|
return! RequestErrors.NOT_FOUND $"The URL {string ctx.Request.Path} was not recognized as a valid URL" next
|
||||||
ctx
|
ctx
|
||||||
}
|
}
|
||||||
|
|
392
src/JobsJobsJobs/App/package-lock.json
generated
392
src/JobsJobsJobs/App/package-lock.json
generated
|
@ -2015,6 +2015,122 @@
|
||||||
"tslint": "^5.20.1",
|
"tslint": "^5.20.1",
|
||||||
"webpack": "^4.0.0",
|
"webpack": "^4.0.0",
|
||||||
"yorkie": "^2.0.0"
|
"yorkie": "^2.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"color-convert": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"chalk": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"ansi-styles": "^4.1.0",
|
||||||
|
"supports-color": "^7.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"color-convert": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"color-name": "~1.1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"color-name": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"fork-ts-checker-webpack-plugin-v5": {
|
||||||
|
"version": "npm:fork-ts-checker-webpack-plugin@5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-SVi+ZAQOGbtAsUWrZvGzz38ga2YqjWvca1pXQFUArIVXqli0lLoDQ8uS0wg0kSpcwpZmaW5jVCZXQebkyUQSsw==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"@babel/code-frame": "^7.8.3",
|
||||||
|
"@types/json-schema": "^7.0.5",
|
||||||
|
"chalk": "^4.1.0",
|
||||||
|
"cosmiconfig": "^6.0.0",
|
||||||
|
"deepmerge": "^4.2.2",
|
||||||
|
"fs-extra": "^9.0.0",
|
||||||
|
"memfs": "^3.1.2",
|
||||||
|
"minimatch": "^3.0.4",
|
||||||
|
"schema-utils": "2.7.0",
|
||||||
|
"semver": "^7.3.2",
|
||||||
|
"tapable": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has-flag": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"lru-cache": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"yallist": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schema-utils": {
|
||||||
|
"version": "2.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
|
||||||
|
"integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/json-schema": "^7.0.4",
|
||||||
|
"ajv": "^6.12.2",
|
||||||
|
"ajv-keywords": "^3.4.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"semver": {
|
||||||
|
"version": "7.3.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
||||||
|
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"lru-cache": "^6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"supports-color": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"has-flag": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"yallist": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/cli-plugin-vuex": {
|
"@vue/cli-plugin-vuex": {
|
||||||
|
@ -2093,6 +2209,44 @@
|
||||||
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
|
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"ansi-styles": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"color-convert": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"chalk": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"ansi-styles": "^4.1.0",
|
||||||
|
"supports-color": "^7.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"color-convert": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"color-name": "~1.1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"color-name": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"fs-extra": {
|
"fs-extra": {
|
||||||
"version": "7.0.1",
|
"version": "7.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
|
||||||
|
@ -2104,6 +2258,13 @@
|
||||||
"universalify": "^0.1.0"
|
"universalify": "^0.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"has-flag": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"jsonfile": {
|
"jsonfile": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||||
|
@ -2113,6 +2274,18 @@
|
||||||
"graceful-fs": "^4.1.6"
|
"graceful-fs": "^4.1.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"loader-utils": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"big.js": "^5.2.2",
|
||||||
|
"emojis-list": "^3.0.0",
|
||||||
|
"json5": "^2.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ssri": {
|
"ssri": {
|
||||||
"version": "8.0.1",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
|
||||||
|
@ -2122,11 +2295,33 @@
|
||||||
"minipass": "^3.1.1"
|
"minipass": "^3.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"supports-color": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"has-flag": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"universalify": {
|
"universalify": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
|
},
|
||||||
|
"vue-loader-v16": {
|
||||||
|
"version": "npm:vue-loader@16.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.3.3.tgz",
|
||||||
|
"integrity": "sha512-/1GzCuQ6MRORbC+leKTKoTGtpQt60bYe0gDGEextSteA2OM+v201FPha5jzmjQzVhRcwieZeUvezAtG5a/e5cw==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"chalk": "^4.1.0",
|
||||||
|
"hash-sum": "^2.0.0",
|
||||||
|
"loader-utils": "^2.0.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -6490,122 +6685,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fork-ts-checker-webpack-plugin-v5": {
|
|
||||||
"version": "npm:fork-ts-checker-webpack-plugin@5.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.2.1.tgz",
|
|
||||||
"integrity": "sha512-SVi+ZAQOGbtAsUWrZvGzz38ga2YqjWvca1pXQFUArIVXqli0lLoDQ8uS0wg0kSpcwpZmaW5jVCZXQebkyUQSsw==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"@babel/code-frame": "^7.8.3",
|
|
||||||
"@types/json-schema": "^7.0.5",
|
|
||||||
"chalk": "^4.1.0",
|
|
||||||
"cosmiconfig": "^6.0.0",
|
|
||||||
"deepmerge": "^4.2.2",
|
|
||||||
"fs-extra": "^9.0.0",
|
|
||||||
"memfs": "^3.1.2",
|
|
||||||
"minimatch": "^3.0.4",
|
|
||||||
"schema-utils": "2.7.0",
|
|
||||||
"semver": "^7.3.2",
|
|
||||||
"tapable": "^1.0.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"ansi-styles": {
|
|
||||||
"version": "4.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
|
||||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"color-convert": "^2.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"chalk": {
|
|
||||||
"version": "4.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
|
|
||||||
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"ansi-styles": "^4.1.0",
|
|
||||||
"supports-color": "^7.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"color-convert": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"color-name": "~1.1.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"color-name": {
|
|
||||||
"version": "1.1.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
|
||||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"has-flag": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"lru-cache": {
|
|
||||||
"version": "6.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
|
||||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"yallist": "^4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"schema-utils": {
|
|
||||||
"version": "2.7.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
|
|
||||||
"integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"@types/json-schema": "^7.0.4",
|
|
||||||
"ajv": "^6.12.2",
|
|
||||||
"ajv-keywords": "^3.4.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"semver": {
|
|
||||||
"version": "7.3.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
|
||||||
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"lru-cache": "^6.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"supports-color": {
|
|
||||||
"version": "7.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
|
||||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"has-flag": "^4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"yallist": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"form-data": {
|
"form-data": {
|
||||||
"version": "2.3.3",
|
"version": "2.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
|
||||||
|
@ -12862,87 +12941,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vue-loader-v16": {
|
|
||||||
"version": "npm:vue-loader@16.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.3.0.tgz",
|
|
||||||
"integrity": "sha512-UDgni/tUVSdwHuQo+vuBmEgamWx88SuSlEb5fgdvHrlJSPB9qMBRF6W7bfPWSqDns425Gt1wxAUif+f+h/rWjg==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"chalk": "^4.1.0",
|
|
||||||
"hash-sum": "^2.0.0",
|
|
||||||
"loader-utils": "^2.0.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"ansi-styles": {
|
|
||||||
"version": "4.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
|
||||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"color-convert": "^2.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"chalk": {
|
|
||||||
"version": "4.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
|
|
||||||
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"ansi-styles": "^4.1.0",
|
|
||||||
"supports-color": "^7.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"color-convert": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"color-name": "~1.1.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"color-name": {
|
|
||||||
"version": "1.1.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
|
||||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"has-flag": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"loader-utils": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"big.js": "^5.2.2",
|
|
||||||
"emojis-list": "^3.0.0",
|
|
||||||
"json5": "^2.1.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"supports-color": {
|
|
||||||
"version": "7.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
|
||||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"has-flag": "^4.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"vue-router": {
|
"vue-router": {
|
||||||
"version": "4.0.10",
|
"version": "4.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.0.10.tgz",
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"serve": "vue-cli-service serve",
|
"serve": "vue-cli-service serve",
|
||||||
"build": "vue-cli-service build",
|
"build": "vue-cli-service build --mode development",
|
||||||
"lint": "vue-cli-service lint"
|
"lint": "vue-cli-service lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { LogOnSuccess } from './types'
|
import { Count, LogOnSuccess, Profile } from './types'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a URL that will access the API
|
* Create a URL that will access the API
|
||||||
|
@ -7,10 +7,31 @@ import { LogOnSuccess } from './types'
|
||||||
*/
|
*/
|
||||||
const apiUrl = (url : string) : string => `http://localhost:5000/api/${url}`
|
const apiUrl = (url : string) : string => `http://localhost:5000/api/${url}`
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create request init parameters
|
||||||
|
*
|
||||||
|
* @param method The method by which the request should be executed
|
||||||
|
* @param user The currently logged-on user
|
||||||
|
* @returns RequestInit parameters
|
||||||
|
*/
|
||||||
|
const reqInit = (method : string, user : LogOnSuccess) : RequestInit => {
|
||||||
|
const headers = new Headers()
|
||||||
|
headers.append('Authorization', `Bearer ${user.jwt}`)
|
||||||
|
return {
|
||||||
|
headers,
|
||||||
|
method
|
||||||
|
// mode: 'cors'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
||||||
|
/** API functions for citizens */
|
||||||
|
citizen: {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log a citizen on
|
* Log a citizen on
|
||||||
|
*
|
||||||
* @param code The authorization code from No Agenda Social
|
* @param code The authorization code from No Agenda Social
|
||||||
* @returns The user result, or an error
|
* @returns The user result, or an error
|
||||||
*/
|
*/
|
||||||
|
@ -19,6 +40,40 @@ export default {
|
||||||
if (resp.status === 200) return await resp.json() as LogOnSuccess
|
if (resp.status === 200) return await resp.json() as LogOnSuccess
|
||||||
return `Error logging on - ${await resp.text()}`
|
return `Error logging on - ${await resp.text()}`
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/** API functions for profiles */
|
||||||
|
profile: {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a profile
|
||||||
|
*
|
||||||
|
* @param id The ID of the profile to retrieve (optional; if omitted, retrieve for the current citizen)
|
||||||
|
* @param user The currently logged-on user
|
||||||
|
* @returns The profile (if found), undefined (if not found), or an error string
|
||||||
|
*/
|
||||||
|
retreive: async (id : string | undefined, user : LogOnSuccess) : Promise<Profile | undefined | string> => {
|
||||||
|
const url = id ? `profile/get/${id}` : 'profile'
|
||||||
|
const resp = await fetch(apiUrl(url), reqInit('GET', user))
|
||||||
|
if (resp.status === 200) return await resp.json() as Profile
|
||||||
|
if (resp.status !== 204) return `Error retrieving profile - ${await resp.text()}`
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count profiles in the system
|
||||||
|
*
|
||||||
|
* @param user The currently logged-on user
|
||||||
|
* @returns A count of profiles within the entire system
|
||||||
|
*/
|
||||||
|
count: async (user : LogOnSuccess) : Promise<number | string> => {
|
||||||
|
const resp = await fetch(apiUrl('profile/count'), reqInit('GET', user))
|
||||||
|
if (resp.status === 200) {
|
||||||
|
const result = await resp.json() as Count
|
||||||
|
return result.count
|
||||||
|
}
|
||||||
|
return `Error counting profiles = ${await resp.text()}`
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export * from './types'
|
export * from './types'
|
||||||
|
|
|
@ -8,3 +8,45 @@ export interface LogOnSuccess {
|
||||||
/** The name of the logged-in citizen */
|
/** The name of the logged-in citizen */
|
||||||
name : string
|
name : string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A skill the job seeker possesses */
|
||||||
|
export interface Skill {
|
||||||
|
/** The ID of the skill */
|
||||||
|
id : string
|
||||||
|
/** A description of the skill */
|
||||||
|
description : string
|
||||||
|
/** Notes regarding this skill (level, duration, etc.) */
|
||||||
|
notes : string | undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A job seeker profile */
|
||||||
|
export interface Profile {
|
||||||
|
/** The ID of the citizen to whom this profile belongs */
|
||||||
|
id : string
|
||||||
|
/** Whether this citizen is actively seeking employment */
|
||||||
|
seekingEmployment : boolean
|
||||||
|
/** Whether this citizen allows their profile to be a part of the publicly-viewable, anonymous data */
|
||||||
|
isPublic : boolean
|
||||||
|
/** The ID of the continent on which the citizen resides */
|
||||||
|
continentId : string
|
||||||
|
/** The region in which the citizen resides */
|
||||||
|
region : string
|
||||||
|
/** Whether the citizen is looking for remote work */
|
||||||
|
remoteWork : boolean
|
||||||
|
/** Whether the citizen is looking for full-time work */
|
||||||
|
fullTime : boolean
|
||||||
|
/** The citizen's professional biography */
|
||||||
|
biography : string
|
||||||
|
/** When the citizen last updated their profile */
|
||||||
|
lastUpdatedOn : number
|
||||||
|
/** The citizen's experience (topical / chronological) */
|
||||||
|
experience : string | undefined
|
||||||
|
/** Skills this citizen possesses */
|
||||||
|
skills : Skill[]
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A count */
|
||||||
|
export interface Count {
|
||||||
|
/** The count being returned */
|
||||||
|
count : number
|
||||||
|
}
|
||||||
|
|
|
@ -3,27 +3,32 @@
|
||||||
<p class="home-link"><router-link to="/">Jobs, Jobs, Jobs</router-link></p>
|
<p class="home-link"><router-link to="/">Jobs, Jobs, Jobs</router-link></p>
|
||||||
<p> </p>
|
<p> </p>
|
||||||
<nav>
|
<nav>
|
||||||
|
<template v-if="!isLoggedOn">
|
||||||
<router-link to="/"><v-icon icon="mdi-home" /> Home</router-link>
|
<router-link to="/"><v-icon icon="mdi-home" /> Home</router-link>
|
||||||
<!-- If not logged in -->
|
|
||||||
<router-link to="/profile/seeking"><v-icon icon="mdi-view-list-outline" /> Job Seekers</router-link>
|
<router-link to="/profile/seeking"><v-icon icon="mdi-view-list-outline" /> Job Seekers</router-link>
|
||||||
<a :href="authUrl"><v-icon icon="mdi-login-variant" /> Log On</a>
|
<a :href="authUrl"><v-icon icon="mdi-login-variant" /> Log On</a>
|
||||||
<!-- If logged in -->
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<router-link to="/citizen/dashboard"><v-icon icon="mdi-view-dashboard-variant" />Dashboard</router-link>
|
||||||
<router-link to="/citizen/profile"><v-icon icon="mdi-pencil" /> Edit Your Profile</router-link>
|
<router-link to="/citizen/profile"><v-icon icon="mdi-pencil" /> Edit Your Profile</router-link>
|
||||||
<router-link to="/profile/search"><v-icon icon="mdi-view-list-outline" /> View Profiles</router-link>
|
<router-link to="/profile/search"><v-icon icon="mdi-view-list-outline" /> View Profiles</router-link>
|
||||||
<router-link to="/success-story/list"><v-icon icon="mdi-thumb-up" /> Success Stories</router-link>
|
<router-link to="/success-story/list"><v-icon icon="mdi-thumb-up" /> Success Stories</router-link>
|
||||||
<router-link to="/citizen/log-off"><v-icon icon="mdi-logout-variant" /> Log Off</router-link>
|
<router-link to="/citizen/log-off"><v-icon icon="mdi-logout-variant" /> Log Off</router-link>
|
||||||
<!-- everyone -->
|
</template>
|
||||||
<router-link to="/how-it-works"><v-icon icon="mdi-help-circle-outline" /> How It Works</router-link>
|
<router-link to="/how-it-works"><v-icon icon="mdi-help-circle-outline" /> How It Works</router-link>
|
||||||
</nav>
|
</nav>
|
||||||
</aside>
|
</aside>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue'
|
import { computed, defineComponent } from 'vue'
|
||||||
|
import { useStore } from '../../store'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'AppNav',
|
name: 'AppNav',
|
||||||
setup () {
|
setup () {
|
||||||
|
const store = useStore()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
/** The authorization URL to which the user should be directed */
|
/** The authorization URL to which the user should be directed */
|
||||||
authUrl: (() => {
|
authUrl: (() => {
|
||||||
|
@ -35,7 +40,10 @@ export default defineComponent({
|
||||||
const respType = 'response_type=code'
|
const respType = 'response_type=code'
|
||||||
// TODO: move NAS base URL to config
|
// TODO: move NAS base URL to config
|
||||||
return `https://noagendasocial.com/oauth/authorize?${client}&${scope}&${redirect}&${respType}`
|
return `https://noagendasocial.com/oauth/authorize?${client}&${scope}&${redirect}&${respType}`
|
||||||
})()
|
})(),
|
||||||
|
|
||||||
|
/** Whether a user is logged in or not */
|
||||||
|
isLoggedOn: computed(() => store.state.user !== undefined)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -49,7 +57,7 @@ aside
|
||||||
a:link, a:visited
|
a:link, a:visited
|
||||||
text-decoration: none
|
text-decoration: none
|
||||||
color: white
|
color: white
|
||||||
font-weight: bold
|
font-weight: 500
|
||||||
.home-link
|
.home-link
|
||||||
font-size: 1.2rem
|
font-size: 1.2rem
|
||||||
text-align: center
|
text-align: center
|
||||||
|
|
|
@ -10,6 +10,10 @@ const routes: Array<RouteRecordRaw> = [
|
||||||
{
|
{
|
||||||
path: '/citizen/authorized',
|
path: '/citizen/authorized',
|
||||||
component: () => import(/* webpackChunkName: "logon" */ '../views/citizen/Authorized.vue')
|
component: () => import(/* webpackChunkName: "logon" */ '../views/citizen/Authorized.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/citizen/dashboard',
|
||||||
|
component: () => import(/* webpackChunkName: "logon" */ '../views/citizen/Dashboard.vue')
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ export default createStore({
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async logOn ({ commit }, code: string) {
|
async logOn ({ commit }, code: string) {
|
||||||
const logOnResult = await api.logOn(code)
|
const logOnResult = await api.citizen.logOn(code)
|
||||||
if (typeof logOnResult === 'string') {
|
if (typeof logOnResult === 'string') {
|
||||||
commit('setLogOnState', logOnResult)
|
commit('setLogOnState', logOnResult)
|
||||||
} else {
|
} else {
|
||||||
|
|
81
src/JobsJobsJobs/App/src/views/citizen/Dashboard.vue
Normal file
81
src/JobsJobsJobs/App/src/views/citizen/Dashboard.vue
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
<template>
|
||||||
|
<h3>Welcome, {{user.name}}</h3>
|
||||||
|
|
||||||
|
<template v-if="profile">
|
||||||
|
<p>
|
||||||
|
Your employment profile was last updated {{profile.lastUpdatedOn}}. Your profile currently lists
|
||||||
|
{{profile.skills.length}} skill<span v-if="profile.skills.length !== 1">s</span>.
|
||||||
|
</p>
|
||||||
|
<p><router-link :to="'/profile/view/' + user.citizenId">View Your Employment Profile</router-link></p>
|
||||||
|
<p v-if="profile.seekingEmployment">
|
||||||
|
Your profile indicates that you are seeking employment. Once you find it,
|
||||||
|
<router-link to="/success-story/add">tell your fellow citizens about it!</router-link>
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<p>
|
||||||
|
You do not have an employment profile established; click “Edit Profile” in the menu to get
|
||||||
|
started!
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
<hr>
|
||||||
|
<p>
|
||||||
|
There <span v-if="profileCount === 1">is</span><span v-else>are</span> <span v-if="profileCount === 0">no</span><span v-else>{{profileCount}}</span>
|
||||||
|
employment profile<span v-if="profileCount !== 1">s</span> from citizens of Gitmo Nation.
|
||||||
|
<span v-if="profileCount > 0">Take a look around and see if you can help them find work!</span>
|
||||||
|
</p>
|
||||||
|
<hr>
|
||||||
|
<p>
|
||||||
|
To see how this application works, check out “How It Works” in the sidebar (last updated June
|
||||||
|
14<sup>th</sup>, 2021).
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, onMounted, Ref, ref } from 'vue'
|
||||||
|
import api, { LogOnSuccess, Profile } from '../../api'
|
||||||
|
import { useStore } from '../../store'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'Dashboard',
|
||||||
|
setup () {
|
||||||
|
const store = useStore()
|
||||||
|
|
||||||
|
/** The currently logged-in user */
|
||||||
|
const user = store.state.user as LogOnSuccess
|
||||||
|
|
||||||
|
/** Error messages from data retrieval */
|
||||||
|
const errorMessage = ref('')
|
||||||
|
|
||||||
|
/** The user's profile */
|
||||||
|
const profile : Ref<Profile | undefined> = ref(undefined)
|
||||||
|
|
||||||
|
/** A count of profiles in the system */
|
||||||
|
const profileCount = ref(0)
|
||||||
|
|
||||||
|
const retrieveData = async () => {
|
||||||
|
const profileResult = await api.profile.retreive(undefined, user)
|
||||||
|
if (typeof profileResult === 'string') {
|
||||||
|
errorMessage.value = profileResult
|
||||||
|
} else if (typeof profileResult !== 'undefined') {
|
||||||
|
profile.value = profileResult
|
||||||
|
}
|
||||||
|
const count = await api.profile.count(user)
|
||||||
|
if (typeof count === 'string') {
|
||||||
|
errorMessage.value = `${errorMessage.value}\n${count}`
|
||||||
|
} else {
|
||||||
|
profileCount.value = count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(retrieveData)
|
||||||
|
|
||||||
|
return {
|
||||||
|
user,
|
||||||
|
errorMessage,
|
||||||
|
profile,
|
||||||
|
profileCount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -1,5 +1,6 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
transpileDependencies: [
|
transpileDependencies: [
|
||||||
'vuetify'
|
'vuetify'
|
||||||
]
|
],
|
||||||
|
outputDir: '../Api/wwwroot'
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user