O nginx processa apenas um bloco de localização em cada nível de aninhamento e, portanto, /login.php é tratado pelo bloco ^~ /login e não pelo bloco ~ \.php$ . Como você só reescreve as declarações nos blocos de localização, na verdade não precisa dos blocos de localização (desde que as correspondências de reescrita sejam específicas o suficiente, quais são as suas). Basta mover suas instruções de reconfiguração para a raiz do bloco server para que as solicitações para /login e /admin ainda usem o bloco \.php$ location:
rewrite ^/$ /index.php last;
rewrite ^(/login)$ $1/ permanent;
rewrite ^/login/$ /login.php last;
rewrite ^/login/(.+\.php)$ /$1 last;
rewrite ^(/admin)$ $1/ permanent;
rewrite ^/admin/$ /page_builder.php last;
rewrite ^/admin/(.+\.php)$ /$1 last;
location ~ \.php$ {
...
}