Multi instance #26
|
@ -360,10 +360,14 @@ module Citizen =
|
||||||
|
|
||||||
/// Find a citizen by their Mastodon username
|
/// Find a citizen by their Mastodon username
|
||||||
let findByMastodonUser (instance : string) (mastodonUser : string) conn =
|
let findByMastodonUser (instance : string) (mastodonUser : string) conn =
|
||||||
r.Table(Table.Citizen)
|
fun c -> task {
|
||||||
.GetAll(r.Array (instance, mastodonUser)).OptArg("index", "instanceUser").Nth(0)
|
let! u =
|
||||||
.RunResultAsync<Citizen>
|
r.Table(Table.Citizen)
|
||||||
|> withReconnOption conn
|
.GetAll(r.Array (instance, mastodonUser)).OptArg("index", "instanceUser").Limit(1)
|
||||||
|
.RunResultAsync<Citizen list> c
|
||||||
|
return u |> List.tryHead
|
||||||
|
}
|
||||||
|
|> withReconn conn
|
||||||
|
|
||||||
/// Add a citizen
|
/// Add a citizen
|
||||||
let add (citizen : Citizen) conn =
|
let add (citizen : Citizen) conn =
|
||||||
|
|
|
@ -202,14 +202,6 @@ module Instances =
|
||||||
return! json ((authConfig ctx).Instances |> Array.map toInstance) next ctx
|
return! json ((authConfig ctx).Instances |> Array.map toInstance) next ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET: /api/instance/[abbr]
|
|
||||||
let byAbbr abbr : HttpHandler =
|
|
||||||
fun next ctx -> task {
|
|
||||||
match (authConfig ctx).Instances |> Array.tryFind (fun it -> it.Abbr = abbr) with
|
|
||||||
| Some inst -> return! json (toInstance inst) next ctx
|
|
||||||
| None -> return! Error.notFound next ctx
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Handlers for /api/listing[s] routes
|
/// Handlers for /api/listing[s] routes
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
|
@ -530,12 +522,7 @@ let allEndpoints = [
|
||||||
DELETE [ route "" Citizen.delete ]
|
DELETE [ route "" Citizen.delete ]
|
||||||
]
|
]
|
||||||
GET_HEAD [ route "/continents" Continent.all ]
|
GET_HEAD [ route "/continents" Continent.all ]
|
||||||
subRoute "/instance" [
|
GET_HEAD [ route "/instances" Instances.all ]
|
||||||
GET_HEAD [
|
|
||||||
route "s" Instances.all
|
|
||||||
routef "/%s" Instances.byAbbr
|
|
||||||
]
|
|
||||||
]
|
|
||||||
subRoute "/listing" [
|
subRoute "/listing" [
|
||||||
GET_HEAD [
|
GET_HEAD [
|
||||||
routef "/%O" Listing.get
|
routef "/%O" Listing.get
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
{
|
{
|
||||||
"name": "jobs-jobs-jobs",
|
"name": "jobs-jobs-jobs",
|
||||||
"version": "2.0.0",
|
"version": "2.1.0",
|
||||||
"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",
|
||||||
"lint": "vue-cli-service lint",
|
"lint": "vue-cli-service lint",
|
||||||
"apiserve": "vue-cli-service build && cd ../Api && dotnet run -c Debug"
|
"apiserve": "vue-cli-service build && cd ../Api && dotnet run -c Debug",
|
||||||
|
"publish": "vue-cli-service build --modern && cd ../Api && dotnet publish -c Release -r linux-x64 --self-contained false"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mdi/js": "^5.9.55",
|
"@mdi/js": "^5.9.55",
|
||||||
|
|
|
@ -40,7 +40,7 @@ export function yesOrNo (cond : boolean) : string {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the display name for a citizen (the first available among real, display, or NAS handle)
|
* Get the display name for a citizen (the first available among real, display, or Mastodon handle)
|
||||||
*
|
*
|
||||||
* @param cit The citizen
|
* @param cit The citizen
|
||||||
* @returns The citizen's display name
|
* @returns The citizen's display name
|
||||||
|
|
|
@ -152,16 +152,7 @@ export default {
|
||||||
* @returns All instances, or an error
|
* @returns All instances, or an error
|
||||||
*/
|
*/
|
||||||
all: async () : Promise<Instance[] | string | undefined> =>
|
all: async () : Promise<Instance[] | string | undefined> =>
|
||||||
apiResult<Instance[]>(await fetch(apiUrl("instances"), { method: "GET" }), "retrieving Mastodon instances"),
|
apiResult<Instance[]>(await fetch(apiUrl("instances"), { method: "GET" }), "retrieving Mastodon instances")
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve a Mastodon instance by its abbreviation
|
|
||||||
*
|
|
||||||
* @param abbr The abbreviation of the Mastodon instance to retrieve
|
|
||||||
* @returns The Mastodon instance (if found), undefined (if not found), or an error string
|
|
||||||
*/
|
|
||||||
byAbbr: async (abbr : string) : Promise<Instance | string | undefined> =>
|
|
||||||
apiResult<Instance>(await fetch(apiUrl(`instance/${abbr}`), { method: "GET" }), "retrieving Mastodon instance")
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/** API functions for job listings */
|
/** API functions for job listings */
|
||||||
|
|
|
@ -10,7 +10,7 @@ import store from "@/store"
|
||||||
import Home from "@/views/Home.vue"
|
import Home from "@/views/Home.vue"
|
||||||
import LogOn from "@/views/citizen/LogOn.vue"
|
import LogOn from "@/views/citizen/LogOn.vue"
|
||||||
|
|
||||||
/** The URL to which the user should be pointed once they have authorized with NAS */
|
/** The URL to which the user should be pointed once they have authorized with Mastodon */
|
||||||
export const AFTER_LOG_ON_URL = "jjj-after-log-on-url"
|
export const AFTER_LOG_ON_URL = "jjj-after-log-on-url"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -121,7 +121,7 @@ const routes: Array<RouteRecordRaw> = [
|
||||||
component: () => import(/* webpackChunkName: "so-long" */ "../views/so-long/DeletionOptions.vue")
|
component: () => import(/* webpackChunkName: "so-long" */ "../views/so-long/DeletionOptions.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/so-long/success/:url",
|
path: "/so-long/success/:abbr",
|
||||||
name: "DeletionSuccess",
|
name: "DeletionSuccess",
|
||||||
component: () => import(/* webpackChunkName: "so-long" */ "../views/so-long/DeletionSuccess.vue")
|
component: () => import(/* webpackChunkName: "so-long" */ "../views/so-long/DeletionSuccess.vue")
|
||||||
},
|
},
|
||||||
|
|
8
src/JobsJobsJobs/App/src/store/actions.ts
Normal file
8
src/JobsJobsJobs/App/src/store/actions.ts
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
/** Logs a user on to Jobs, Jobs, Jobs */
|
||||||
|
export const LogOn = "logOn"
|
||||||
|
|
||||||
|
/** Ensures that the continent list in the state has been populated */
|
||||||
|
export const EnsureContinents = "ensureContinents"
|
||||||
|
|
||||||
|
/** Ensures that the Mastodon instance list in the state has been populated */
|
||||||
|
export const EnsureInstances = "ensureInstances"
|
|
@ -1,6 +1,8 @@
|
||||||
import { InjectionKey } from "vue"
|
import { InjectionKey } from "vue"
|
||||||
import { createStore, Store, useStore as baseUseStore } from "vuex"
|
import { createStore, Store, useStore as baseUseStore } from "vuex"
|
||||||
import api, { Continent, LogOnSuccess } from "../api"
|
import api, { Continent, Instance, LogOnSuccess } from "../api"
|
||||||
|
import * as Actions from "./actions"
|
||||||
|
import * as Mutations from "./mutations"
|
||||||
|
|
||||||
/** The state tracked by the application */
|
/** The state tracked by the application */
|
||||||
export interface State {
|
export interface State {
|
||||||
|
@ -10,6 +12,8 @@ export interface State {
|
||||||
logOnState: string
|
logOnState: string
|
||||||
/** All continents (use `ensureContinents` action) */
|
/** All continents (use `ensureContinents` action) */
|
||||||
continents: Continent[]
|
continents: Continent[]
|
||||||
|
/** All instances (use `ensureInstances` action) */
|
||||||
|
instances: Instance[]
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An injection key to identify this state with Vue */
|
/** An injection key to identify this state with Vue */
|
||||||
|
@ -25,42 +29,50 @@ export default createStore({
|
||||||
return {
|
return {
|
||||||
user: undefined,
|
user: undefined,
|
||||||
logOnState: "<em>Welcome back!</em>",
|
logOnState: "<em>Welcome back!</em>",
|
||||||
continents: []
|
continents: [],
|
||||||
|
instances: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
setUser (state, user : LogOnSuccess) {
|
[Mutations.SetUser]: (state, user : LogOnSuccess) => { state.user = user },
|
||||||
state.user = user
|
[Mutations.ClearUser]: (state) => { state.user = undefined },
|
||||||
},
|
[Mutations.SetLogOnState]: (state, message : string) => { state.logOnState = message },
|
||||||
clearUser (state) {
|
[Mutations.SetContinents]: (state, continents : Continent[]) => { state.continents = continents },
|
||||||
state.user = undefined
|
[Mutations.SetInstances]: (state, instances : Instance[]) => { state.instances = instances }
|
||||||
},
|
|
||||||
setLogOnState (state, message : string) {
|
|
||||||
state.logOnState = message
|
|
||||||
},
|
|
||||||
setContinents (state, continents : Continent[]) {
|
|
||||||
state.continents = continents
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async logOn ({ commit }, { abbr, code }) {
|
[Actions.LogOn]: async ({ commit }, { abbr, code }) => {
|
||||||
const logOnResult = await api.citizen.logOn(abbr, code)
|
const logOnResult = await api.citizen.logOn(abbr, code)
|
||||||
if (typeof logOnResult === "string") {
|
if (typeof logOnResult === "string") {
|
||||||
commit("setLogOnState", logOnResult)
|
commit(Mutations.SetLogOnState, logOnResult)
|
||||||
} else {
|
} else {
|
||||||
commit("setUser", logOnResult)
|
commit(Mutations.SetUser, logOnResult)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async ensureContinents ({ state, commit }) {
|
[Actions.EnsureContinents]: async ({ state, commit }) => {
|
||||||
if (state.continents.length > 0) return
|
if (state.continents.length > 0) return
|
||||||
const theSeven = await api.continent.all()
|
const theSeven = await api.continent.all()
|
||||||
if (typeof theSeven === "string") {
|
if (typeof theSeven === "string") {
|
||||||
console.error(theSeven)
|
console.error(theSeven)
|
||||||
} else {
|
} else {
|
||||||
commit("setContinents", theSeven)
|
commit(Mutations.SetContinents, theSeven)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[Actions.EnsureInstances]: async ({ state, commit }) => {
|
||||||
|
if (state.instances.length > 0) return
|
||||||
|
const instResp = await api.instances.all()
|
||||||
|
if (typeof instResp === "string") {
|
||||||
|
console.error(instResp)
|
||||||
|
} else if (typeof instResp === "undefined") {
|
||||||
|
console.error("No instances were found; this should not happen")
|
||||||
|
} else {
|
||||||
|
commit(Mutations.SetInstances, instResp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
modules: {
|
modules: {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export * as Actions from "./actions"
|
||||||
|
export * as Mutations from "./mutations"
|
||||||
|
|
14
src/JobsJobsJobs/App/src/store/mutations.ts
Normal file
14
src/JobsJobsJobs/App/src/store/mutations.ts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/** Set the logged-on user */
|
||||||
|
export const SetUser = "setUser"
|
||||||
|
|
||||||
|
/** Clear the logged-on user */
|
||||||
|
export const ClearUser = "clearUser"
|
||||||
|
|
||||||
|
/** Set the status of the current log on action */
|
||||||
|
export const SetLogOnState = "setLogOnState"
|
||||||
|
|
||||||
|
/** Set the list of continents */
|
||||||
|
export const SetContinents = "setContinents"
|
||||||
|
|
||||||
|
/** Set the list of Mastodon instances */
|
||||||
|
export const SetInstances = "setInstances"
|
|
@ -13,14 +13,13 @@ article
|
||||||
h4 Description of Service and Registration
|
h4 Description of Service and Registration
|
||||||
p
|
p
|
||||||
| Jobs, Jobs, Jobs is a service that allows individuals to enter and amend employment profiles, restricting access
|
| Jobs, Jobs, Jobs is a service that allows individuals to enter and amend employment profiles, restricting access
|
||||||
| to the details of these profiles to other users of
|
| to the details of these profiles to other users of No Agenda-afilliated Mastodon sites (currently
|
||||||
= " "
|
= " "
|
||||||
template(v-for="(it, idx) in instances" :key="idx")
|
template(v-for="(it, idx) in instances" :key="idx")
|
||||||
a(:href="it.url" target="_blank") {{it.name}}
|
a(:href="it.url" target="_blank") {{it.name}}
|
||||||
template(v-if="idx + 2 < instances.length")= ", "
|
template(v-if="idx + 2 < instances.length")= ", "
|
||||||
template(v-else-if="idx + 1 < instances.length")= ", and "
|
template(v-else-if="idx + 1 < instances.length")= ", and "
|
||||||
template(v-else)= ". "
|
| ). Registration is accomplished by allowing Jobs, Jobs, Jobs to read one’s Mastodon profile. See our
|
||||||
| Registration is accomplished by allowing Jobs, Jobs, Jobs to read one’s Mastodon profile. See our
|
|
||||||
= " "
|
= " "
|
||||||
router-link(to="/privacy-policy") privacy policy
|
router-link(to="/privacy-policy") privacy policy
|
||||||
= " "
|
= " "
|
||||||
|
@ -51,21 +50,14 @@ article
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, Ref, ref } from "vue"
|
import { computed, onMounted } from "vue"
|
||||||
|
import { useStore, Actions } from "@/store"
|
||||||
|
|
||||||
import api, { Instance } from "@/api"
|
const store = useStore()
|
||||||
import { toastError } from "@/components/layout/AppToaster.vue"
|
|
||||||
|
|
||||||
const instances : Ref<Instance[]> = ref([])
|
/** All instances authorized to view Jobs, Jobs, Jobs */
|
||||||
|
const instances = computed(() => store.state.instances)
|
||||||
|
|
||||||
|
onMounted(async () => { await store.dispatch(Actions.EnsureInstances) })
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
const apiResp = await api.instances.all()
|
|
||||||
if (typeof apiResp === "string") {
|
|
||||||
toastError(apiResp, "retrieving instances")
|
|
||||||
} else if (typeof apiResp === "undefined") {
|
|
||||||
toastError("No instances to display", undefined)
|
|
||||||
} else {
|
|
||||||
instances.value = apiResp
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -8,8 +8,7 @@ article
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted } from "vue"
|
import { computed, onMounted } from "vue"
|
||||||
import { useRoute, useRouter } from "vue-router"
|
import { useRoute, useRouter } from "vue-router"
|
||||||
import api from "@/api"
|
import { useStore, Actions, Mutations } from "@/store"
|
||||||
import { useStore } from "@/store"
|
|
||||||
import { AFTER_LOG_ON_URL } from "@/router"
|
import { AFTER_LOG_ON_URL } from "@/router"
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
|
@ -20,20 +19,19 @@ const router = useRouter()
|
||||||
const abbr = route.params.abbr as string
|
const abbr = route.params.abbr as string
|
||||||
|
|
||||||
/** Set the message for this component */
|
/** Set the message for this component */
|
||||||
const setMessage = (msg : string) => store.commit("setLogOnState", msg)
|
const setMessage = (msg : string) => store.commit(Mutations.SetLogOnState, msg)
|
||||||
|
|
||||||
/** Pass the code to the API and exchange it for a user and a JWT */
|
/** Pass the code to the API and exchange it for a user and a JWT */
|
||||||
const logOn = async () => {
|
const logOn = async () => {
|
||||||
const instance = await api.instances.byAbbr(abbr)
|
await store.dispatch(Actions.EnsureInstances)
|
||||||
if (typeof instance === "string") {
|
const instance = store.state.instances.find(it => it.abbr === abbr)
|
||||||
setMessage(instance)
|
if (typeof instance === "undefined") {
|
||||||
} else if (typeof instance === "undefined") {
|
|
||||||
setMessage(`Mastodon instance ${abbr} not found`)
|
setMessage(`Mastodon instance ${abbr} not found`)
|
||||||
} else {
|
} else {
|
||||||
setMessage(`<em>Welcome back! Verifying your ${instance.name} account…</em>`)
|
setMessage(`<em>Welcome back! Verifying your ${instance.name} account…</em>`)
|
||||||
const code = route.query.code
|
const code = route.query.code
|
||||||
if (code) {
|
if (code) {
|
||||||
await store.dispatch("logOn", { abbr, code })
|
await store.dispatch(Actions.LogOn, { abbr, code })
|
||||||
if (store.state.user !== undefined) {
|
if (store.state.user !== undefined) {
|
||||||
const afterLogOnUrl = window.localStorage.getItem(AFTER_LOG_ON_URL)
|
const afterLogOnUrl = window.localStorage.getItem(AFTER_LOG_ON_URL)
|
||||||
if (afterLogOnUrl) {
|
if (afterLogOnUrl) {
|
||||||
|
|
|
@ -6,7 +6,8 @@ article.container
|
||||||
.col: .card.h-100
|
.col: .card.h-100
|
||||||
h5.card-header Your Profile
|
h5.card-header Your Profile
|
||||||
.card-body
|
.card-body
|
||||||
h6.card-subtitle.mb-3.text-muted.fst-italic Last updated #[full-date-time(:date="profile.lastUpdatedOn")]
|
h6.card-subtitle.mb-3.text-muted.fst-italic(v-if="profile").
|
||||||
|
Last updated #[full-date-time(:date="profile.lastUpdatedOn")]
|
||||||
p.card-text(v-if="profile")
|
p.card-text(v-if="profile")
|
||||||
| Your profile currently lists {{profile.skills.length}}
|
| Your profile currently lists {{profile.skills.length}}
|
||||||
| skill#[template(v-if="profile.skills.length !== 1") s].
|
| skill#[template(v-if="profile.skills.length !== 1") s].
|
||||||
|
|
|
@ -6,9 +6,9 @@ article
|
||||||
.col-12.col-sm-10.col-md-8.col-lg-6
|
.col-12.col-sm-10.col-md-8.col-lg-6
|
||||||
.form-floating
|
.form-floating
|
||||||
input.form-control(type="text" id="realName" v-model="v$.realName.$model" maxlength="255"
|
input.form-control(type="text" id="realName" v-model="v$.realName.$model" maxlength="255"
|
||||||
placeholder="Leave blank to use your NAS display name")
|
placeholder="Leave blank to use your Mastodon display name")
|
||||||
label(for="realName") Real Name
|
label(for="realName") Real Name
|
||||||
.form-text Leave blank to use your NAS display name
|
.form-text Leave blank to use your Mastodon display name
|
||||||
.col-12
|
.col-12
|
||||||
.form-check
|
.form-check
|
||||||
input.form-check-input(type="checkbox" id="isSeeking" v-model="v$.isSeekingEmployment.$model")
|
input.form-check-input(type="checkbox" id="isSeeking" v-model="v$.isSeekingEmployment.$model")
|
||||||
|
|
|
@ -9,13 +9,13 @@ article
|
||||||
import { onMounted } from "vue"
|
import { onMounted } from "vue"
|
||||||
import { useRouter } from "vue-router"
|
import { useRouter } from "vue-router"
|
||||||
import { toastSuccess } from "@/components/layout/AppToaster.vue"
|
import { toastSuccess } from "@/components/layout/AppToaster.vue"
|
||||||
import { useStore } from "@/store"
|
import { useStore, Mutations } from "@/store"
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
store.commit("clearUser")
|
store.commit(Mutations.ClearUser)
|
||||||
toastSuccess("Log Off Successful | <strong>Have a Nice Day!</strong>")
|
toastSuccess("Log Off Successful | <strong>Have a Nice Day!</strong>")
|
||||||
router.push("/")
|
router.push("/")
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,22 +1,24 @@
|
||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
article
|
article
|
||||||
p
|
p
|
||||||
load-data(:load="retrieveInstances")
|
p.fst-italic(v-if="selected") Sending you over to {{selected.name}} to log on; see you back in just a second…
|
||||||
p.fst-italic(v-if="selected") Sending you over to {{selected.name}} to log on; see you back in just a second…
|
template(v-else)
|
||||||
template(v-else)
|
p.text-center Please select your No Agenda-affiliated Mastodon instance
|
||||||
p.text-center Please select your No Agenda-affiliated Mastodon instance
|
p.text-center(v-for="it in instances" :key="it.abbr")
|
||||||
p.text-center(v-for="it in instances" :key="it.abbr")
|
button.btn.btn-primary(@click.prevent="select(it.abbr)") {{it.name}}
|
||||||
button.btn.btn-primary(@click.prevent="select(it.abbr)") {{it.name}}
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, Ref, ref } from "vue"
|
import { computed, onMounted, Ref, ref } from "vue"
|
||||||
import api, { Instance } from "@/api"
|
import { Instance } from "@/api"
|
||||||
|
import { useStore, Actions } from "@/store"
|
||||||
|
|
||||||
import LoadData from "@/components/LoadData.vue"
|
import LoadData from "@/components/LoadData.vue"
|
||||||
|
|
||||||
|
const store = useStore()
|
||||||
|
|
||||||
/** The instances configured for Jobs, Jobs, Jobs */
|
/** The instances configured for Jobs, Jobs, Jobs */
|
||||||
const instances : Ref<Instance[]> = ref([])
|
const instances = computed(() => store.state.instances)
|
||||||
|
|
||||||
/** Whether authorization is in progress */
|
/** Whether authorization is in progress */
|
||||||
const selected : Ref<Instance | undefined> = ref(undefined)
|
const selected : Ref<Instance | undefined> = ref(undefined)
|
||||||
|
@ -43,15 +45,6 @@ const select = (abbr : string) => {
|
||||||
document.location.assign(authUrl.value)
|
document.location.assign(authUrl.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Load the instances we have configured */
|
onMounted(async () => { await store.dispatch(Actions.EnsureInstances) })
|
||||||
const retrieveInstances = async (errors : string[]) => {
|
|
||||||
const instancesResp = await api.instances.all()
|
|
||||||
if (typeof instancesResp === "string") {
|
|
||||||
errors.push(instancesResp)
|
|
||||||
} else if (typeof instancesResp === "undefined") {
|
|
||||||
errors.push("No instances found (this should not happen)")
|
|
||||||
} else {
|
|
||||||
instances.value = instancesResp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -65,7 +65,7 @@ const title = computed(() => it.value ? `${it.value.listing.title} | Job Listing
|
||||||
/** The HTML details of the job listing */
|
/** The HTML details of the job listing */
|
||||||
const details = computed(() => toHtml(it.value?.listing.text ?? ""))
|
const details = computed(() => toHtml(it.value?.listing.text ?? ""))
|
||||||
|
|
||||||
/** The NAS profile URL for the citizen who posted this job listing */
|
/** The Mastodon profile URL for the citizen who posted this job listing */
|
||||||
const profileUrl = computed(() => citizen.value ? citizen.value.profileUrl : "")
|
const profileUrl = computed(() => citizen.value ? citizen.value.profileUrl : "")
|
||||||
|
|
||||||
/** The needed by date, formatted in SHOUTING MODE */
|
/** The needed by date, formatted in SHOUTING MODE */
|
||||||
|
|
|
@ -21,14 +21,14 @@ article
|
||||||
p.text-center: button.btn.btn-danger(@click.prevent="deleteAccount") Delete Your Entire Account
|
p.text-center: button.btn.btn-danger(@click.prevent="deleteAccount") Delete Your Entire Account
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { onMounted } from "vue"
|
||||||
import { useRouter } from "vue-router"
|
import { useRouter } from "vue-router"
|
||||||
|
|
||||||
import api, { LogOnSuccess } from "@/api"
|
import api, { LogOnSuccess } from "@/api"
|
||||||
import { toastError, toastSuccess } from "@/components/layout/AppToaster.vue"
|
import { toastError, toastSuccess } from "@/components/layout/AppToaster.vue"
|
||||||
import { useStore } from "@/store"
|
import { useStore, Actions, Mutations } from "@/store"
|
||||||
</script>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
|
@ -54,21 +54,22 @@ const deleteAccount = async () => {
|
||||||
} else if (typeof citizenResp === "undefined") {
|
} else if (typeof citizenResp === "undefined") {
|
||||||
toastError("Could not retrieve citizen record", undefined)
|
toastError("Could not retrieve citizen record", undefined)
|
||||||
} else {
|
} else {
|
||||||
const instResp = await api.instances.byAbbr(citizenResp.instance)
|
const instance = store.state.instances.find(it => it.abbr === citizenResp.instance)
|
||||||
if (typeof instResp === "string") {
|
if (typeof instance === "undefined") {
|
||||||
toastError(instResp, "retriving instance")
|
|
||||||
} else if (typeof instResp === "undefined") {
|
|
||||||
toastError("Could not retrieve instance", undefined)
|
toastError("Could not retrieve instance", undefined)
|
||||||
} else {
|
} else {
|
||||||
const resp = await api.citizen.delete(user)
|
const resp = await api.citizen.delete(user)
|
||||||
if (typeof resp === "string") {
|
if (typeof resp === "string") {
|
||||||
toastError(resp, "Deleting Account")
|
toastError(resp, "Deleting Account")
|
||||||
} else {
|
} else {
|
||||||
store.commit("clearUser")
|
store.commit(Mutations.ClearUser)
|
||||||
toastSuccess("Account Deleted Successfully")
|
toastSuccess("Account Deleted Successfully")
|
||||||
router.push(`/so-long/success/${instResp.url}`)
|
router.push(`/so-long/success/${instance.abbr}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(async () => { await store.dispatch(Actions.EnsureInstances) })
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -11,11 +11,19 @@ article
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { computed, onMounted } from "vue"
|
||||||
import { useRoute } from "vue-router"
|
import { useRoute } from "vue-router"
|
||||||
|
import { useStore, Actions } from "@/store"
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
const store = useStore()
|
||||||
|
|
||||||
/** The URL of the instance from which the deleted user had authorized access */
|
/** The abbreviation of the instance from which the deleted user had authorized access */
|
||||||
const url = route.params.url as string
|
const abbr = route.params.abbr as string
|
||||||
|
|
||||||
|
/** The URL of that instance */
|
||||||
|
const url = computed(() => store.state.instances.find(it => it.abbr === abbr)?.url ?? "")
|
||||||
|
|
||||||
|
onMounted(async () => { await store.dispatch(Actions.EnsureInstances) })
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -31,7 +31,7 @@ const user = store.state.user as LogOnSuccess
|
||||||
/** The story to be displayed */
|
/** The story to be displayed */
|
||||||
const story : Ref<Success | undefined> = ref(undefined)
|
const story : Ref<Success | undefined> = ref(undefined)
|
||||||
|
|
||||||
/** The citizen's name (real, display, or NAS, whichever is found first) */
|
/** The citizen's name (real, display, or Mastodon, whichever is found first) */
|
||||||
const citizenName = ref("")
|
const citizenName = ref("")
|
||||||
|
|
||||||
/** Retrieve the success story */
|
/** Retrieve the success story */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user