11import express from 'express' ;
2- import AdminForth , { AdminForthDataTypes , AdminUser , Filters } from 'adminforth' ;
2+ import AdminForth , { Filters } from 'adminforth' ;
3+ import usersResource from "./resources/users" ;
4+ import apartmentsResource from "./resources/apartments" ;
5+ import auditLogsResource from "./resources/auditLogs"
6+
7+
8+ const ADMIN_BASE_URL = '' ;
39
410export const admin = new AdminForth ( {
5- baseUrl : '' ,
11+ baseUrl : ADMIN_BASE_URL ,
612 auth : {
713 usersResourceId : 'users' , // resource to get user during login
814 usernameField : 'email' , // field where username is stored, should exist in resource
9- passwordHashField : 'passwordHash' ,
15+ passwordHashField : 'password_hash' ,
16+ rememberMeDays : 30 , // users who will check "remember me" will stay logged in for 30 days
1017 } ,
1118 customization : {
1219 brandName : 'My Admin' ,
1320 datesFormat : 'D MMM YY' ,
1421 timeFormat : 'HH:mm:ss' ,
1522 emptyFieldPlaceholder : '-' ,
1623 } ,
17- dataSources : [ {
18- id : 'maindb' ,
19- url : `sqlite://${ process . env . DATABASE_FILE } ` ,
20- } ] ,
21- resources : [
24+ dataSources : [
2225 {
23- dataSource : 'maindb' ,
24- table : 'user' ,
25- resourceId : 'users' ,
26- label : 'Users' ,
27- recordLabel : ( r : any ) => `👤 ${ r . email } ` ,
28- columns : [
29- {
30- name : 'id' ,
31- primaryKey : true ,
32- fillOnCreate : ( ) => Math . random ( ) . toString ( 36 ) . substring ( 7 ) ,
33- showIn : [ 'list' , 'filter' , 'show' ] ,
34- } ,
35- {
36- name : 'email' ,
37- required : true ,
38- isUnique : true ,
39- enforceLowerCase : true ,
40- validation : [
41- AdminForth . Utils . EMAIL_VALIDATOR ,
42- ]
43- } ,
44- {
45- name : 'createdAt' ,
46- type : AdminForthDataTypes . DATETIME ,
47- showIn : [ 'list' , 'filter' , 'show' ] ,
48- fillOnCreate : ( ) => ( new Date ( ) ) . toISOString ( ) ,
49- } ,
50- {
51- name : 'role' ,
52- enum : [
53- { value : 'superadmin' , label : 'Super Admin' } ,
54- { value : 'user' , label : 'User' } ,
55- ]
56- } ,
57- {
58- name : 'password' ,
59- virtual : true ,
60- required : { create : true } ,
61- editingNote : { edit : 'Leave empty to keep password unchanged' } ,
62- minLength : 8 ,
63- type : AdminForthDataTypes . STRING ,
64- showIn : [ 'create' , 'edit' ] ,
65- masked : true ,
66- } ,
67- { name : 'passwordHash' , backendOnly : true , showIn : [ ] }
68- ] ,
26+ id : 'maindb' ,
27+ url : `sqlite://${ process . env . DATABASE_FILE } `
6928 } ,
70- {
71- table : 'post' ,
72- resourceId : 'posts' ,
73- dataSource : 'maindb' ,
74- label : 'Posts' ,
75- recordLabel : ( r : any ) => `📝 ${ r . title } ` ,
76- columns : [
77- {
78- name : 'id' ,
79- primaryKey : true ,
80- fillOnCreate : ( ) => Math . random ( ) . toString ( 36 ) . substring ( 7 ) ,
81- showIn : [ 'list' , 'filter' , 'show' ] ,
82- } ,
83- {
84- name : 'title' ,
85- type : AdminForthDataTypes . STRING ,
86- required : true ,
87- showIn : [ 'list' , 'create' , 'edit' , 'filter' , 'show' ] ,
88- maxLength : 255 ,
89- minLength : 3 ,
90- } ,
91- {
92- name : 'content' ,
93- showIn : [ 'list' , 'create' , 'edit' , 'filter' , 'show' ] ,
94- } ,
95- {
96- name : 'createdAt' ,
97- showIn : [ 'list' , 'filter' , 'show' , ] ,
98- fillOnCreate : ( ) => ( new Date ( ) ) . toISOString ( ) ,
99- } ,
100- {
101- name : 'published' ,
102- required : true ,
103- } ,
104- {
105- name : 'authorId' ,
106- foreignResource : {
107- resourceId : 'users' ,
108- } ,
109- showIn : [ 'list' , 'filter' , 'show' ] ,
110- fillOnCreate : ( { adminUser } : { adminUser : AdminUser } ) => {
111- return adminUser . dbUser . id ;
112- }
113- }
114- ] ,
115- }
29+ ] ,
30+ resources : [
31+ apartmentsResource ,
32+ usersResource ,
33+ auditLogsResource
11634 ] ,
11735 menu : [
11836 {
@@ -122,15 +40,27 @@ export const admin = new AdminForth({
12240 children : [
12341 {
12442 homepage : true ,
125- label : 'Posts ' ,
43+ label : 'Apartments ' ,
12644 icon : 'flowbite:home-solid' ,
127- resourceId : 'posts ' ,
45+ resourceId : 'aparts ' ,
12846 } ,
47+ {
48+ label : 'Audit Logs' ,
49+ icon : 'flowbite:search-outline' ,
50+ resourceId : 'audit_logs' ,
51+ }
12952 ]
13053 } ,
131- { type : 'gap' } ,
132- { type : 'divider' } ,
133- { type : 'heading' , label : 'SYSTEM' } ,
54+ {
55+ type : 'gap'
56+ } ,
57+ {
58+ type : 'divider'
59+ } ,
60+ {
61+ type : 'heading' ,
62+ label : 'SYSTEM' ,
63+ } ,
13464 {
13565 label : 'Users' ,
13666 icon : 'flowbite:user-solid' ,
@@ -139,32 +69,53 @@ export const admin = new AdminForth({
13969 ] ,
14070} ) ;
14171
72+ async function seedDatabase ( ) {
73+ if ( await admin . resource ( 'aparts' ) . count ( ) > 0 ) {
74+ return
75+ }
76+ for ( let i = 0 ; i <= 50 ; i ++ ) {
77+ await admin . resource ( 'aparts' ) . create ( {
78+ id : `${ i } ` ,
79+ title : `Apartment ${ i } ` ,
80+ square_meter : ( Math . random ( ) * 100 ) . toFixed ( 1 ) ,
81+ price : ( Math . random ( ) * 10000 ) . toFixed ( 2 ) ,
82+ number_of_rooms : Math . floor ( Math . random ( ) * 4 ) + 1 ,
83+ description : 'Next gen apartments' ,
84+ created_at : ( new Date ( Date . now ( ) - Math . random ( ) * 60 * 60 * 24 * 14 * 1000 ) ) . toISOString ( ) ,
85+ listed : i % 2 == 0 ,
86+ country : `${ [ 'US' , 'DE' , 'FR' , 'GB' , 'NL' , 'IT' , 'ES' , 'DK' , 'PL' , 'UA' ] [ Math . floor ( Math . random ( ) * 10 ) ] } `
87+ } ) ;
88+ } ;
89+ } ;
14290
14391if ( import . meta. url === `file://${ process . argv [ 1 ] } ` ) {
14492 // if script is executed directly e.g. node index.ts or npm start
14593
94+
14695 const app = express ( )
14796 app . use ( express . json ( ) ) ;
14897 const port = 3500 ;
14998
15099 // needed to compile SPA. Call it here or from a build script e.g. in Docker build time to reduce downtime
151- await admin . bundleNow ( { hotReload : process . env . NODE_ENV === 'development' } ) ;
100+ await admin . bundleNow ( { hotReload : process . env . NODE_ENV === 'development' } ) ;
152101 console . log ( 'Bundling AdminForth done. For faster serving consider calling bundleNow() from a build script.' ) ;
153102
103+
154104 // serve after you added all api
155105 admin . express . serve ( app )
156106
157107 admin . discoverDatabases ( ) . then ( async ( ) => {
158108 if ( ! await admin . resource ( 'users' ) . get ( [ Filters . EQ ( 'email' , 'adminforth' ) ] ) ) {
159109 await admin . resource ( 'users' ) . create ( {
160110 email : 'adminforth' ,
161- passwordHash : await AdminForth . Utils . generatePasswordHash ( 'adminforth' ) ,
111+ password_hash : await AdminForth . Utils . generatePasswordHash ( 'adminforth' ) ,
162112 role : 'superadmin' ,
163113 } ) ;
164114 }
115+ await seedDatabase ( ) ;
165116 } ) ;
166117
167- admin . express . listen ( port , ( ) => {
168- console . log ( `\n⚡ AdminForth is available at http://localhost:${ port } \n` )
118+ admin . express . expressApp . listen ( port , ( ) => {
119+ console . log ( `\n⚡ AdminForth is available at http://localhost:${ port } ${ ADMIN_BASE_URL } \n` )
169120 } ) ;
170121}
0 commit comments