11import { ArticleStatus } from '#enums/article_status'
2+ import { Role } from '#enums/role'
23import Article from '#models/article'
34import ArticleStatsService from '#services/article_stats_service'
45import { articleValidator } from '#validators/article_validator'
@@ -49,8 +50,9 @@ export default class ArticlesController {
4950 return inertia . render ( 'articles/[slug]' , { article } )
5051 }
5152
52- async dashboard ( { inertia } : HttpContext ) {
53- const stats = await ArticleStatsService . getStats ( )
53+ async dashboard ( { inertia, auth } : HttpContext ) {
54+ // Chaque utilisateur ne voit que ses propres statistiques
55+ const stats = await ArticleStatsService . getStats ( auth . user ! . id )
5456 return inertia . render ( 'dashboard/index' , {
5557 publishedArticles : stats . published ,
5658 draftArticles : stats . drafts ,
@@ -59,4 +61,127 @@ export default class ArticlesController {
5961 questions : 0 ,
6062 } )
6163 }
64+
65+ async articles ( { inertia, request, auth } : HttpContext ) {
66+ const page = request . input ( 'page' , 1 )
67+ const status = request . input ( 'status' , null )
68+
69+ const query = Article . query ( )
70+ . preload ( 'author' )
71+ . where ( 'author_id' , auth . user ! . id )
72+ . orderBy ( 'created_at' , 'desc' )
73+
74+ if ( status && Object . values ( ArticleStatus ) . includes ( status as ArticleStatus ) ) {
75+ query . where ( 'status' , status as ArticleStatus )
76+ }
77+
78+ const articles = await query . paginate ( page , 10 )
79+
80+ return inertia . render ( 'dashboard/articles' , {
81+ articles : articles . toJSON ( ) ,
82+ currentStatus : status ,
83+ } )
84+ }
85+
86+ async edit ( { inertia, params, auth, response } : HttpContext ) {
87+ const article = await Article . query ( )
88+ . where ( 'slug' , params . slug )
89+ . where ( 'author_id' , auth . user ! . id )
90+ . firstOrFail ( )
91+
92+ return inertia . render ( 'dashboard/articles/edit' , { article } )
93+ }
94+
95+ async update ( { request, params, auth, response } : HttpContext ) {
96+ const article = await Article . query ( )
97+ . where ( 'slug' , params . slug )
98+ . where ( 'author_id' , auth . user ! . id )
99+ . firstOrFail ( )
100+
101+ const data = await articleValidator . validate ( request . all ( ) )
102+
103+ const payload : Partial < Article > = { ...data }
104+
105+ // Si on passe de draft/waiting à published, mettre à jour publishedAt
106+ if (
107+ data . status === ArticleStatus . PUBLISHED &&
108+ article . status !== ArticleStatus . PUBLISHED
109+ ) {
110+ payload . publishedAt = DateTime . now ( )
111+ }
112+
113+ // Si le titre change, générer un nouveau slug
114+ if ( data . title !== article . title ) {
115+ payload . slug = Article . generateSlug ( data . title )
116+ }
117+
118+ await article . merge ( payload ) . save ( )
119+
120+ return response . redirect ( ) . toRoute ( 'articles.show' , { slug : article . slug } )
121+ }
122+
123+ // ADMIN METHODS
124+
125+ /**
126+ * Liste des articles pour l'admin
127+ * - Tous les articles publiés (de tous les auteurs)
128+ * - Ses propres brouillons seulement
129+ */
130+ async adminArticles ( { inertia, request, auth } : HttpContext ) {
131+ const page = request . input ( 'page' , 1 )
132+ const status = request . input ( 'status' , null )
133+
134+ let query = Article . query ( ) . preload ( 'author' ) . orderBy ( 'created_at' , 'desc' )
135+
136+ if ( status && Object . values ( ArticleStatus ) . includes ( status as ArticleStatus ) ) {
137+ if ( status === ArticleStatus . PUBLISHED ) {
138+ // Admin voit tous les articles publiés
139+ query . where ( 'status' , ArticleStatus . PUBLISHED )
140+ } else {
141+ // Admin ne voit que ses propres brouillons/en attente
142+ query . where ( 'status' , status as ArticleStatus ) . where ( 'author_id' , auth . user ! . id )
143+ }
144+ } else {
145+ // Par défaut : tous les publiés + ses brouillons
146+ query . where ( ( builder ) => {
147+ builder
148+ . where ( 'status' , ArticleStatus . PUBLISHED )
149+ . orWhere ( ( subBuilder ) => {
150+ subBuilder . where ( 'author_id' , auth . user ! . id ) . whereIn ( 'status' , [
151+ ArticleStatus . DRAFT ,
152+ ArticleStatus . WAITING_APPROVAL ,
153+ ] )
154+ } )
155+ } )
156+ }
157+
158+ const articles = await query . paginate ( page , 10 )
159+
160+ return inertia . render ( 'admin/articles' , {
161+ articles : articles . toJSON ( ) ,
162+ currentStatus : status ,
163+ } )
164+ }
165+
166+ /**
167+ * Dépublier un article (admin seulement)
168+ * Passe le statut de PUBLISHED à DRAFT
169+ */
170+ async unpublish ( { params, response, session, auth } : HttpContext ) {
171+ const article = await Article . query ( ) . where ( 'slug' , params . slug ) . firstOrFail ( )
172+
173+ // Vérifier que l'article est publié
174+ if ( article . status !== ArticleStatus . PUBLISHED ) {
175+ session . flash ( 'error' , 'Cet article n\'est pas publié' )
176+ return response . redirect ( ) . back ( )
177+ }
178+
179+ // Dépublier l'article
180+ article . status = ArticleStatus . DRAFT
181+ article . publishedAt = null
182+ await article . save ( )
183+
184+ session . flash ( 'success' , 'Article dépublié avec succès' )
185+ return response . redirect ( ) . back ( )
186+ }
62187}
0 commit comments