auth: add JWT email/password auth + Login UI; security: kms rotate helper; preview sync endpoint + UI
This commit is contained in:
@@ -1,13 +1,15 @@
|
||||
import React from 'react'
|
||||
import Integrations from './Integrations'
|
||||
import Guilds from './Guilds'
|
||||
import Login from './Login'
|
||||
|
||||
export default function App(){
|
||||
return (
|
||||
<div style={{padding:20,fontFamily:'system-ui, sans-serif'}}>
|
||||
<h1>LifeRPG Modern</h1>
|
||||
<p>Welcome — frontend scaffold. Connect to backend at <code>/api/v1</code>.</p>
|
||||
<Integrations />
|
||||
<Login />
|
||||
<Integrations />
|
||||
<Guilds />
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -30,6 +30,14 @@ export default function Integrations(){
|
||||
.finally(()=>setLoadingId(null))
|
||||
}
|
||||
|
||||
function previewEvents(integrationId){
|
||||
fetch(`/api/v1/integrations/${integrationId}/events_preview`, {credentials:'include'})
|
||||
.then(r=>r.json()).then(d=>{
|
||||
setEvents(d)
|
||||
setMsg('Preview loaded')
|
||||
}).catch(()=>setMsg('Preview failed'))
|
||||
}
|
||||
|
||||
function removeIntegration(integrationId){
|
||||
if(!confirm('Remove integration?')) return
|
||||
setLoadingId(integrationId)
|
||||
@@ -63,6 +71,7 @@ export default function Integrations(){
|
||||
<strong>{i.provider}</strong> — id: {i.id} — user: {i.user_id}
|
||||
<div style={{display:'inline-block', marginLeft:12}}>
|
||||
<button onClick={()=>fetchEvents(i.id)} disabled={loadingId===i.id} style={{marginRight:6}}>Fetch Events</button>
|
||||
<button onClick={()=>previewEvents(i.id)} disabled={loadingId===i.id} style={{marginRight:6}}>Preview</button>
|
||||
<button onClick={()=>syncIntegration(i.id)} disabled={loadingId===i.id} style={{marginRight:6}}>Sync → Habits</button>
|
||||
<button onClick={()=>removeIntegration(i.id)} disabled={loadingId===i.id}>Remove</button>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import React, {useState} from 'react'
|
||||
|
||||
export default function Login(){
|
||||
const [email,setEmail]=useState('')
|
||||
const [pw,setPw]=useState('')
|
||||
const [msg,setMsg]=useState(null)
|
||||
|
||||
function submit(e){
|
||||
e.preventDefault()
|
||||
fetch('/api/v1/auth/login', {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({email, password: pw}), credentials:'include'})
|
||||
.then(r=>r.json()).then(()=> setMsg('Logged in')).catch(()=> setMsg('Login failed'))
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{marginTop:20}}>
|
||||
<h2>Login</h2>
|
||||
<form onSubmit={submit}>
|
||||
<div><input placeholder="email" value={email} onChange={e=>setEmail(e.target.value)} /></div>
|
||||
<div><input placeholder="password" type="password" value={pw} onChange={e=>setPw(e.target.value)} /></div>
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
{msg && <div style={{marginTop:8}}>{msg}</div>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user