Created my first wordpress plugin template page, need comments
First of all, your plugin is not translation ready, see l18n. In the plugin header, you should add

* Text Domain: your-textdomain
* Domain Path: /languages


Create the language files in wp-content/plugins/your-plugin/languages with PoEdit. And make all relevant strings translatable with:

add_menu_page( __('Plugin title','your-textdomain'), ...
// and
&lt;?php _e('Options saved','your-textdomain'); ?&gt;




There's a big issue: you're printing your styles and scripts all over the admin area. It's essential that you always target the correct page.

add_action( 'admin_menu', 'my_first_plugin_add_page' );
function my_first_plugin_add_page() 
{
    $hook = add_menu_page(
        'plugin title', 
        'plugin title', 
        'manage_options', 
        'my_first_plugin', 
        'my_first_plugin_do_page'
    );
    add_action( "admin_print_scripts-$hook", 'my_first_plugin_scripts' );   
}




You don't need to close and open PHP tags if you're not swapping between PHP and HTML:

*/
?&gt;
&lt;?php
function my_first_plugin_init(){


Get rid of the very last ?&gt; too.
See Why do some scripts omit the closing php tag ?&gt;.



It's easier to have a general picture if you declare first the hooks and then the callbacks.

add_action('first_hook', 'prefix_first_callback');
add_action('second_hook', 'prefix_second_callback');
add_filter('third_hook', 'prefix_third_callback');
function prefix_first_callback() {}
function prefix_second_callback() {}
function prefix_third_callback() {}




It's important to prefix everything, function names, meta data and $_POSTed data. But for function names this quickly turns into hard to read code. Encapsulating everything in a class avoids this. And also allows us to start-up our plugin in a safe point: plugins_loaded, see Best way to initiate a class in a WP plugin?.

The following is a clean version of Plugin Class Demo, by toscho◆. Please, go to the source for the full documented class.

add_action(
    'plugins_loaded',
    array ( PREFIX_My_Plugin::get_instance(), 'plugin_setup' )
);

class PREFIX_My_Plugin
{
    protected static $instance = NULL;
    public $plugin_url = '';
    public $plugin_path = '';

    public static function get_instance()
    {
        NULL === self::$instance and self::$instance = new self;
        return self::$instance;
    }

    public function plugin_setup()
    {
        $this-&gt;plugin_url    = plugins_url( '/', __FILE__ );
        $this-&gt;plugin_path   = plugin_dir_path( __FILE__ );
        $this-&gt;load_language( 'plugin_unique_name' );
        // Your stuff: register actions and filters
        add_action( 'admin_init', array( $this, '_admin_init' ) );
    }

    public function _admin_init()
    {
        // your_stuff();
    }

    public function __construct() {}

    public function load_language( $domain )
    {
        load_plugin_textdomain(
            $domain,
            FALSE,
            $this-&gt;plugin_path . 'languages'
        );
    }
}